How does wealth relate to health?
In this project, we seek to explore the relationships between income levels and health, as income is frequently brought up as one of the social determinants of health. We will explore this relationship at multiple levels: international, national, and local levels.
Two main indicators of health are health outcomes, such as life expectancy, and health insurance coverage. The health insurance is especially a big challenge in the United States, given its highly fragmented healthcare system and payment model. In this project, we aim to explore how these measures vary over time and across geography.
Life expectancy: International, national, state-level
At the international level, we looked at life expectancy as a function of GDP per capita. From 1952 to 2007, life expectancy has increased overall, and we can clearly see that in most countries, as the national wealth increases, the life expectancy also increases.
p <- ggplot(gapminder, aes(x = gdpPercap, y=lifeExp, size = pop, colour = country)) +
geom_point(show.legend = FALSE, alpha = 0.7) +
scale_color_viridis_d() +
scale_size(range = c(2, 12)) +
scale_x_log10() +
theme_economist() +
labs(x="Weath (GDP per capita)",
y="Life expectancy",
title = "Life Expectancy vs. Income in the world",
caption = "Source: IHME")
p <- p + transition_time(year) +
labs(title = "Life expectancy vs. GDP by country: {frame_time}")+
view_follow(fixed_y = TRUE)
anim_save("life.gif")
This pattern continues at the national level in the US: The richest American men live 15 years longer than the poorest men, while the richest American women live 10 years longer than the poorest women.
Note: the size of the points represents the number of people in different countries.
df1 <- read.csv("Data/health_ineq_online_table_1.csv")
df1 <- df1 %>% mutate(gnd = ifelse(gnd=="F", "Female", "Male"))
p1 <- ggplot(df1, aes(pctile, le_raceadj),alpha = 1)+
geom_line(aes(color=gnd))+
theme_economist() +
labs(x="\nHousehold income percentile",
y="Life expectancy at age 40\n",
title = "Life expectancy vs. income in the US\n",
caption = "Source: Health Inequality Project") +
scale_color_brewer(palette = "Dark2") +
theme(axis.line = element_line(colour = "black"),
plot.title = element_text(face = "bold.italic", hjust = 0.5),
legend.position = "top", legend.title = element_blank())
p1

df3 <- read.csv("Data/health_ineq_online_table_3_female.csv")
df3_2001 <-gather(df3,incomepetile,life,Q1:Q4,factor_key = TRUE)
name <- c("California", "Texas", "Florida", "New York", "Pennsylvania", "Illinois", "Ohio", "Georgia")
df_sub <- df3_2001%>%
filter(statename %in% name)
p3 <- ggplot(data = df_sub, aes(y = life, x = incomepetile,color = statename, group = statename))+
geom_line(size = 1)+
theme_bw()+
theme_economist() +
scale_color_brewer(palette = "Dark2") +
labs(x="\nHousehold income quartile",
y="Life expectancy at age 40\n",
title = "Female life expectancy vs. income\n",
caption = "Source: Health Inequality Project") +
theme(axis.line = element_line(colour = "black"),
plot.title = element_text(face = "bold.italic", hjust = 0.5))+
theme(legend.position = "right", legend.title = element_blank())
p3

df4 <- read.csv("Data/health_ineq_online_table_3_male.csv")
df4_2001 <-gather(df4,incomepetile,life,Q1:Q4,factor_key = TRUE)
df_sub_2 <- df4_2001%>%
filter(statename %in% name)
p4 <- ggplot(data = df_sub_2, aes(y = life, x = incomepetile,color = statename, group = statename))+
geom_line(size = 1)+
theme_bw()+
theme_economist() +
scale_color_brewer(palette = "Dark2") +
labs(x="\nHousehold income quartile",
y="Life expectancy at age 40\n",
title = "Male life expectancy vs. income\n",
caption = "Source: Health Inequality Project") +
theme(axis.line = element_line(colour = "black"),
plot.title = element_text(face = "bold.italic", hjust = 0.5))+
theme(legend.position = "right", legend.title = element_blank())
p4

Health outcomes at the local level
Diabetes
Diabetes <- read_csv("Data/DiabetesData.csv")
Diabetes <- Diabetes %>%
mutate(STATECOUNTYFP = str_pad(`CountyFIPS`, 5, "left", pad = "0"), Percentage = as.numeric(Percentage))
countydiabetes <- merge(lower48, Diabetes, by = "STATECOUNTYFP", duplicateGeoms = TRUE)
countydiabetesincome <- merge(countydiabetes, Income, by = c("STATECOUNTYFP", "Year"), duplicateGeoms = TRUE) %>%
mutate(year = as.integer(year))
countydiabetesincome$adjustedrate <- countydiabetesincome$Percentage/countydiabetesincome$income_per_capita
This plot demonstrates a clear correlation between diabetes rates and income, with higher income counties having lower rates of diabetes. It also shows that while diabetes has increased everywhere over time, the increases have been far more pronounced for poorer counties. Note especially the sharp spike in rates over 2015-2016
diabetesplot <- ggplot(filter(countydiabetesincome, income_per_capita < 100000),
aes(x = income_per_capita, y = Percentage, color = region_name)) +
geom_jitter(alpha = .7) +
theme_economist() +
scale_color_brewer(palette = "Dark2") +
labs(x="\nIncome per capita",
title = "Diabetes rate vs. income\n",
caption = "Source: CDC") +
scale_y_continuous(labels = function(x) paste0(x, "%")) +
scale_x_continuous(labels = dollar) +
theme(axis.line = element_line(colour = "black"),
plot.title = element_text(face = "bold.italic", hjust = 0.5),
legend.position = "top", legend.title = element_blank(),
axis.title.y = element_blank())
diabetesplotanim <- diabetesplot + transition_time(year) +
labs(title = "Diabetes rate vs. income: {frame_time}\n")
diabetesplotanim
anim_save("diabetesplotanim.gif")
The first map shows diabetes rates as a percentage of the population for each county in the US. The second maps an adjusted metric, the diabetes ratio/per-capita income ratio. This income-adjusted adjuested ratio is intended to account for variance due to income. Geographic differences in diabetes rates are more muted in the adjusted map, indicating that some of the differences in diabetes levels are actually the result of income clustering.
diabetes <- tm_shape(filter(countydiabetes, Year == "2016")) +
tm_fill(col = "Percentage", title = "", pal = "YlOrRd", n = 5) +
tm_layout(frame = FALSE, legend.format = list(
fun = function(x) paste0(formatC(x, digits = 0, format = "f"), "%")))
tmap_save(diabetes, "diabetes_counties_2016_map.png")
diabetes_adjusted <- tm_shape(filter(countydiabetesincome, Year == "2016")) +
tm_fill(col = "adjustedrate", title = "Diabetes-to-\nincome ratio", pal = "YlOrRd", n = 5) +
tm_layout(frame = FALSE, legend.format = list(
fun = function(x) paste0(formatC(x, digits = 4, format = "f"))))
tmap_save(diabetes_adjusted, "diabetes_income_ratio_counties_2016_map.png")
Life expectancy
LifeExp <- read_csv("Data/ExpectancyData.csv")
LifeExp <- LifeExp %>%
mutate(clean_lifeexp = as.numeric(str_extract(`Life expectancy`, "^\\d*.\\d*")),
STATECOUNTYFP = str_pad(`FIPS`, 5, "left", pad = "0"))
countylife <- merge(lower48, LifeExp, by = "STATECOUNTYFP", duplicateGeoms = TRUE)
countylifeincome <- merge(countylife, Income, by = c("STATECOUNTYFP", "Year"), duplicateGeoms = TRUE) %>%
mutate(year = as.integer(year))
countylifeincome$adjustedrate <- countylifeincome$clean_lifeexp/countylifeincome$income_per_capita
This plot demonstrates a clear relatinoship between life expectancy and income, with higher income counties having higher average life expectancy. There is a worrying pattern of life expectancy increasing for higher-income counties while life expectancy is constant or falling in lower-income counties.
lifeplot <- ggplot(filter(countylifeincome, income_per_capita < 100000),
aes(x = income_per_capita, y = clean_lifeexp, color = region_name)) +
geom_jitter(alpha = .7) +
theme_economist() +
scale_color_brewer(palette = "Dark2") +
labs(x="\nIncome per capita",
title = "Life expectancy vs. income\n",
caption = "Source: IHME") +
scale_x_continuous(labels = dollar) +
theme(axis.line = element_line(colour = "black"),
plot.title = element_text(face = "bold.italic", hjust = 0.5),
legend.position = "top", legend.title = element_blank(),
axis.title.y = element_blank())
lifeplotanim <- lifeplot + transition_time(year) +
labs(title = "Life expectancy vs. income: {frame_time}")
lifeplotanim
anim_save("lifeplotanim.gif")
The first map shows life expectancy for each county in the US. The second maps an adjusted metric, life expectancy/income per capita. Geographic differences in life expectancy (intensity of color variation) are significantly more muted in the adjusted map, indicating that much of the variance in life expectancy is the result of income clustering. The poor counties experiencing decreasing life expectancy are largely in the South and Midwest.
Regular map
life_expectancy <- tm_shape(filter(countylife, Year == "2014")) +
tm_fill(col = "clean_lifeexp", title = "", pal = "YlGn", n = 5) +
tm_layout(frame = FALSE, legend.format = list(
fun = function(x) paste0(formatC(x, digits = 0, format = "f"))))
tmap_save(life_expectancy, "life_expectancy_counties_2014_map.png")
life_expectancy_adjusted <- tm_shape(filter(countylifeincome, Year == "2014")) +
tm_fill(col = "adjustedrate", title = "Life expectancy-to-\nincome ratio", pal = "YlGn", n = 5) +
tm_layout(frame = FALSE, legend.format = list(
fun = function(x) paste0(formatC(x, digits = 3, format = "f"))))
tmap_save(life_expectancy_adjusted, "life_expectancy_adjusted_counties_2014_map.png")
Infant mortality
im_data <- read_excel("Data/Linked_Birth_Infant_Death_Records_per_1000_by_County_and_Year_Died_2007-2017.xlsx")
im_data <- im_data %>%
mutate(STATECOUNTYFP = str_pad(`County Code`, 5, "left", pad = "0"),
Deathrate = as.numeric(`Death Rate`))
countyinfant <- merge(lower48, im_data, by = "STATECOUNTYFP", duplicateGeoms = TRUE)
countyinfantincome <- merge(im_data, Income, by = "STATECOUNTYFP", duplicateGeoms = TRUE) %>%
mutate(year = as.integer(year))
countyinfantincome$adjustedrate <- countyinfantincome$Deathrate/countyinfantincome$income_per_capita
Infant mortality shows a clear correlation to income, with higher income counties having lower infant mortality. Neither the pattern nor the overall incidence of child mortality appears to be changing.
infantplot <- ggplot(filter(countyinfantincome, income_per_capita < 100000),
aes(x = income_per_capita, y = Deathrate, color = region_name)) +
geom_jitter(alpha = .7) +
theme_economist() +
scale_color_brewer(palette = "Dark2") +
labs(x="\nIncome per capita",
y = "Deaths per 1,000 live births\n",
title = "Infant mortality vs. income\n",
caption = "Source: CDC") +
scale_x_continuous(labels = dollar) +
theme(axis.line = element_line(colour = "black"),
plot.title = element_text(face = "bold.italic", hjust = 0.5),
legend.position = "top", legend.title = element_blank())
infantplotanim <- infantplot + transition_time(year) +
labs(title = "Infant mortality vs. income: {frame_time}")
infantplotanim
anim_save("infantplotanim.gif")
Health insurance
In this section, we aim to further our investigation of income and health outcomes by adding in the major player in this linkage – healthcare insurance. Specifically, we focus on the uninsured population and aim to use visualizations to showcase the influence of income on uninsurance rate.
Our base data came from the Small Area Health Insurance Estimates (SAHIE) from the Census Bureau, which was extracted from the American Community Survey (ACS) conducted yearly. We narrowed our focus on the period of 2008 to 2018 for data completeness and consistency considerations. We believe the usage of as recent as possible data would be most ideal (for which the latest possible was year 2018), and we aimed to have a long enough period to detect/showcase any trends. We believe 10 years is a good time frame. We also hereby note that the SAHIE only started to utilize the ACS as the basis for its estimates in 2008, prior to which it used the Annual Social and Economic Supplement to the Current Population Survey (CPS ASEC).
Note: The definition of health insurance coverage in the ACS is - “Is this person CURRENTLY covered by [specifically stated] health insurance or health coverage plans?”
# Loading data
sahie_2008 <- read.csv("Data/sahie_2008_FIPS.csv", header = TRUE)
sahie_2009 <- read.csv("Data/sahie_2009_FIPS.csv", header = TRUE)
sahie_2010 <- read.csv("Data/sahie_2010_FIPS.csv", header = TRUE)
sahie_2011 <- read.csv("Data/sahie_2011_FIPS.csv", header = TRUE)
sahie_2012 <- read.csv("Data/sahie_2012_FIPS.csv", header = TRUE)
sahie_2013 <- read.csv("Data/sahie_2013_FIPS.csv", header = TRUE)
sahie_2014 <- read.csv("Data/sahie_2014_FIPS.csv", header = TRUE)
sahie_2015 <- read.csv("Data/sahie_2015_FIPS.csv", header = TRUE)
sahie_2016 <- read.csv("Data/sahie_2016_FIPS.csv", header = TRUE)
sahie_2017 <- read.csv("Data/sahie_2017_FIPS.csv", header = TRUE)
sahie_2018 <- read.csv("Data/sahie_2018_FIPS.csv", header = TRUE)
How are income levels related to the uninsurance rate? We chose to focus on the 138% of the Federal Poverty Level (FPL) and the 250% of FPL. The reasoning is that for the population with income level below the 138% FPL, if their states expanded Medicaid under the Affordable Care Act (ACA, signed into law by President Obama in 2010 and went into effect starting 2014), they may qualify for Medicaid or CHIP. Population that earns an income below the 250% FPL may qualify for out-of-pocket cost assistance on Silver plans sold through the Marketplace.
From the above graphic, we can see that the lower the income, although with some level of assistance, the higher uninsurance rate across the 10 year period. We can also observe clearly that the uninsurance rate dropped significantly between 2013 and 2014, because of the ACA.
Hover over data points of interest
income <- read.csv("Data/Hongjue_BEA_Income_Per_Capita_by_State_1990-2019.csv")
income <- income %>% mutate(fips = ifelse(str_length(GeoFips) < 5, paste0(0, GeoFips), GeoFips)) %>%
select(-GeoFips) %>%
filter(year %in% 2008:2018)
state_simple <- state_0818 %>% select(year, NUI, NIPR, fips)
inc_insur <- left_join(income, state_simple)
p2 <- ggplot(inc_insur, aes(x=NUI/NIPR, y=income_per_capita, color=GeoName, alpha=0.7, shape=as.factor(year),
text = paste('</br> Year: ', year,
'</br> State: ', GeoName,
'</br> Uninsured percentage: ', round(NUI/NIPR,2),
'</br> Income level: ', income_per_capita))) +
geom_point() +
theme_economist() +
scale_color_viridis_d() +
scale_x_continuous(labels = percent_format(accuracy = 1)) +
scale_y_continuous(labels = dollar) +
theme(axis.line = element_line(colour = "black"),
plot.title = element_text(face = "bold.italic", hjust = 0.5),
legend.position = "none") +
labs(title = "How does income affect the uninsurance rate?", subtitle = "States by color, years by shape") +
xlab("Rate of uninsurance") +
ylab("Income per capita\n")
ggplotly(p2, tooltip = "text", height = 400, width=780) %>%
config(displayModeBar = FALSE) %>%
layout(hoverlabel = list(bgcolor = "white", font = list(family = "Georgia")))
Here is a more detailed look into this income-uninsurance relationship. We can see that, in general, the lower the income per capita (of a certain state in a given year), the higher the state-level uninsured rate. (Note: States are differentiated using color and years are differentiated using shape.)
To visualize this in a map, we created a Leaflet map with separate layers for the uninsurance rate and income level, shown below for the years 2008-2018 (averaged). The color density corresponds to the uninsurance rate and the average income per capita, respectively. Using this visualization we can observe that in general, the northeast and west coast regions had higher incomes per capita, while the souths, midwest, and Alaska were struggling with the highest uninsurance rate.
dt <- inc_insur %>%
mutate(uninsured = round(NUI/NIPR,2), state = as.character(GeoName)) %>%
select(year, state, uninsured, income_per_capita) %>%
mutate_geocode(state)
# dt_year <- dt %>% filter(year==2008)
dt_year <- dt %>% group_by(state) %>%
summarise(income_per_capita=mean(income_per_capita), uninsured=mean(uninsured),
lon=mean(lon), lat=mean(lat)) %>%
mutate(state=as.factor(state))
states.merged <- merge(x=states, y=dt_year, by.x="NAME", by.y="state")
pal1 <- colorBin("YlOrRd", domain = states.merged$uninsured, bins = c(0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3))
pal2 <- colorBin("BuGn", domain = states.merged$income_per_capita, bins = c(20000:85000))
popup = paste("State: ", states.merged@data$NAME,
"<br>Income per capita: ", round(states.merged@data$income_per_capita,2),
"<br>Uninsured rate: ", round(states.merged@data$uninsured,2))
leaflet(states.merged) %>% addTiles() %>%
setView(-96, 37.8, 4) %>%
addPolygons(fillColor = ~pal1(uninsured),
fillOpacity = 0.6, color = "darkgrey", weight = 1.5,
popup = popup, group="Uninsured rate")%>%
addPolygons(fillColor = ~pal2(income_per_capita),
fillOpacity = 1, color = "white", weight = 2.0,
popup = popup, group="Income level") %>%
addLayersControl(
baseGroups = c("Uninsurance rate", "Income level"),
options = layersControlOptions(collapsed = FALSE))
# height="100%", width="100%"
To make it clearer and easier to understand, we created a data table for our users to explore the statistics of their interest:
LS0tCnRpdGxlOiAnR3JvdXAgQiBGaW5hbCBQcm9qZWN0OiBJbmNvbWUgYW5kIEhlYWx0aGNhcmUnCmF1dGhvcjoKLSBuYW1lOiBIb25nanVlIFdhbmcKLSBuYW1lOiBBbGlzb24gUnlsYW5kCi0gbmFtZTogVG9sdSBCdWtvbGEKLSBuYW1lOiBYdW4gV2VpCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCICVZJylgIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogICAgdG9jOiB5ZXMKICBodG1sX25vdGVib29rOgogICAgZmlnX2NhcHRpb246IHllcwogICAgdGhlbWU6IHVuaXRlZAogICAgdG9jOiB5ZXMKICBwZGZfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlID0gRkFMU0UsIGVjaG89RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkKI2RldnRvb2xzOjppbnN0YWxsX2dpdGh1YigiZGthaGxlL2dnbWFwIikKbGlicmFyeShnZ21hcCkKbGlicmFyeShodHRwdXYpCnJlZ2lzdGVyX2dvb2dsZShrZXkgPSBTeXMuZ2V0ZW52KCJHT09HTEVfTUFQU19BUElfS0VZIikpCmBgYAoKIyBIb3cgZG9lcyB3ZWFsdGggcmVsYXRlIHRvIGhlYWx0aD8KCkluIHRoaXMgcHJvamVjdCwgd2Ugc2VlayB0byBleHBsb3JlIHRoZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gaW5jb21lIGxldmVscyBhbmQgaGVhbHRoLCBhcyBpbmNvbWUgaXMgZnJlcXVlbnRseSBicm91Z2h0IHVwIGFzIG9uZSBvZiB0aGUgc29jaWFsIGRldGVybWluYW50cyBvZiBoZWFsdGguIFdlIHdpbGwgZXhwbG9yZSB0aGlzIHJlbGF0aW9uc2hpcCBhdCBtdWx0aXBsZSBsZXZlbHM6IGludGVybmF0aW9uYWwsIG5hdGlvbmFsLCBhbmQgbG9jYWwgbGV2ZWxzLiAKClR3byBtYWluIGluZGljYXRvcnMgb2YgaGVhbHRoIGFyZSBoZWFsdGggb3V0Y29tZXMsIHN1Y2ggYXMgbGlmZSBleHBlY3RhbmN5LCBhbmQgaGVhbHRoIGluc3VyYW5jZSBjb3ZlcmFnZS4gVGhlIGhlYWx0aCBpbnN1cmFuY2UgaXMgZXNwZWNpYWxseSBhIGJpZyBjaGFsbGVuZ2UgaW4gdGhlIFVuaXRlZCBTdGF0ZXMsIGdpdmVuIGl0cyBoaWdobHkgZnJhZ21lbnRlZCBoZWFsdGhjYXJlIHN5c3RlbSBhbmQgcGF5bWVudCBtb2RlbC4gSW4gdGhpcyBwcm9qZWN0LCB3ZSBhaW0gdG8gZXhwbG9yZSBob3cgdGhlc2UgbWVhc3VyZXMgdmFyeSBvdmVyIHRpbWUgYW5kIGFjcm9zcyBnZW9ncmFwaHkuCgojIyBMaWZlIGV4cGVjdGFuY3k6IEludGVybmF0aW9uYWwsIG5hdGlvbmFsLCBzdGF0ZS1sZXZlbAoKYGBge3IsIGV2YWw9VFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIGVjaG89RkFMU0V9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShwbG90bHkpCmxpYnJhcnkoZ2FwbWluZGVyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdnYW5pbWF0ZSkKbGlicmFyeShnZ3RoZW1lcykKbGlicmFyeShnZ21hcCkKbGlicmFyeShSQ29sb3JCcmV3ZXIpCmxpYnJhcnkodG1hcCkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkobGVhZmxldCkKbGlicmFyeShyZ2VvcykKbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkocmdkYWwpCmxpYnJhcnkobGVhZnN5bmMpCmxpYnJhcnkoYWNzKQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkoc3ApCmxpYnJhcnkodGlncmlzKQojbGlicmFyeShzaGlueSkKI2xpYnJhcnkoc2hpbnl0aGVtZXMpCmxpYnJhcnkobWFwdG9vbHMpCmxpYnJhcnkobWFnaWNrKQpsaWJyYXJ5KHNjYWxlcykKbGlicmFyeShyZWFkeGwpCmxpYnJhcnkodGlkeXRleHQpCmxpYnJhcnkocmVhZHIpCmxpYnJhcnkoRFQpCmxpYnJhcnkoZ2dhbHQpCmxpYnJhcnkodHJhbnNmb3JtcikKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KGhyYnJ0aGVtZXMpCmxpYnJhcnkoZ3JpZEV4dHJhKQojbGlicmFyeSh1cmJubWFwcikKbGlicmFyeSh0aWR5Y2Vuc3VzKQpsaWJyYXJ5KGdyaWQpCmxpYnJhcnkoZ2Vvc3BoZXJlKQpsaWJyYXJ5KGx3Z2VvbSkKbGlicmFyeShzZikKYGBgCgpBdCB0aGUgaW50ZXJuYXRpb25hbCBsZXZlbCwgd2UgbG9va2VkIGF0IGxpZmUgZXhwZWN0YW5jeSBhcyBhIGZ1bmN0aW9uIG9mIEdEUCBwZXIgY2FwaXRhLiBGcm9tIDE5NTIgdG8gMjAwNywgbGlmZSBleHBlY3RhbmN5IGhhcyBpbmNyZWFzZWQgb3ZlcmFsbCwgYW5kIHdlIGNhbiBjbGVhcmx5IHNlZSB0aGF0IGluIG1vc3QgY291bnRyaWVzLCBhcyB0aGUgbmF0aW9uYWwgd2VhbHRoIGluY3JlYXNlcywgdGhlIGxpZmUgZXhwZWN0YW5jeSBhbHNvIGluY3JlYXNlcy4KCmBgYHtyLCBldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwIDwtIGdncGxvdChnYXBtaW5kZXIsIGFlcyh4ID0gZ2RwUGVyY2FwLCB5PWxpZmVFeHAsIHNpemUgPSBwb3AsIGNvbG91ciA9IGNvdW50cnkpKSArCiAgZ2VvbV9wb2ludChzaG93LmxlZ2VuZCA9IEZBTFNFLCBhbHBoYSA9IDAuNykgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZCgpICsKICBzY2FsZV9zaXplKHJhbmdlID0gYygyLCAxMikpICsKICBzY2FsZV94X2xvZzEwKCkgKwogIHRoZW1lX2Vjb25vbWlzdCgpICsKICBsYWJzKHg9IldlYXRoIChHRFAgcGVyIGNhcGl0YSkiLCAKICAgICAgIHk9IkxpZmUgZXhwZWN0YW5jeSIsCiAgICAgICB0aXRsZSA9ICJMaWZlIEV4cGVjdGFuY3kgdnMuIEluY29tZSBpbiB0aGUgd29ybGQiLAogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IElITUUiKQoKcCA8LSBwICsgdHJhbnNpdGlvbl90aW1lKHllYXIpICsKICBsYWJzKHRpdGxlID0gIkxpZmUgZXhwZWN0YW5jeSB2cy4gR0RQIGJ5IGNvdW50cnk6IHtmcmFtZV90aW1lfSIpKwogIHZpZXdfZm9sbG93KGZpeGVkX3kgPSBUUlVFKQphbmltX3NhdmUoImxpZmUuZ2lmIikKYGBgCiFbTGlmZSBleHBlY3RhbmN5IHZzLiBHRFBdKEltYWdlcy9saWZlLmdpZikKClRoaXMgcGF0dGVybiBjb250aW51ZXMgYXQgdGhlIG5hdGlvbmFsIGxldmVsIGluIHRoZSBVUzogVGhlIHJpY2hlc3QgQW1lcmljYW4gbWVuIGxpdmUgMTUgeWVhcnMgbG9uZ2VyIHRoYW4gdGhlIHBvb3Jlc3QgbWVuLCB3aGlsZSB0aGUgcmljaGVzdCBBbWVyaWNhbiB3b21lbiBsaXZlIDEwIHllYXJzIGxvbmdlciB0aGFuIHRoZSBwb29yZXN0IHdvbWVuLgoKTm90ZTogdGhlIHNpemUgb2YgdGhlIHBvaW50cyByZXByZXNlbnRzIHRoZSBudW1iZXIgb2YgcGVvcGxlIGluIGRpZmZlcmVudCBjb3VudHJpZXMuCgpgYGB7ciwgZXZhbD1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpkZjEgPC0gcmVhZC5jc3YoIkRhdGEvaGVhbHRoX2luZXFfb25saW5lX3RhYmxlXzEuY3N2IikKZGYxIDwtIGRmMSAlPiUgbXV0YXRlKGduZCA9IGlmZWxzZShnbmQ9PSJGIiwgIkZlbWFsZSIsICJNYWxlIikpCgpwMSA8LSBnZ3Bsb3QoZGYxLCBhZXMocGN0aWxlLCBsZV9yYWNlYWRqKSxhbHBoYSA9IDEpKwogIGdlb21fbGluZShhZXMoY29sb3I9Z25kKSkrCiAgdGhlbWVfZWNvbm9taXN0KCkgKwogIGxhYnMoeD0iXG5Ib3VzZWhvbGQgaW5jb21lIHBlcmNlbnRpbGUiLCAKICAgICAgIHk9IkxpZmUgZXhwZWN0YW5jeSBhdCBhZ2UgNDBcbiIsCiAgICAgICB0aXRsZSA9ICJMaWZlIGV4cGVjdGFuY3kgdnMuIGluY29tZSBpbiB0aGUgVVNcbiIsCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogSGVhbHRoIEluZXF1YWxpdHkgUHJvamVjdCIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpICsKICB0aGVtZShheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQuaXRhbGljIiwgaGp1c3QgPSAwLjUpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpCgpwMQpgYGAKCmBgYHtyLCBldmFsPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmRmMyA8LSByZWFkLmNzdigiRGF0YS9oZWFsdGhfaW5lcV9vbmxpbmVfdGFibGVfM19mZW1hbGUuY3N2IikKCmRmM18yMDAxIDwtZ2F0aGVyKGRmMyxpbmNvbWVwZXRpbGUsbGlmZSxRMTpRNCxmYWN0b3Jfa2V5ID0gVFJVRSkKCm5hbWUgPC0gYygiQ2FsaWZvcm5pYSIsICJUZXhhcyIsICJGbG9yaWRhIiwgIk5ldyBZb3JrIiwgIlBlbm5zeWx2YW5pYSIsICJJbGxpbm9pcyIsICJPaGlvIiwgIkdlb3JnaWEiKQoKZGZfc3ViIDwtIGRmM18yMDAxJT4lCiAgZmlsdGVyKHN0YXRlbmFtZSAlaW4lIG5hbWUpCgpwMyA8LSBnZ3Bsb3QoZGF0YSA9IGRmX3N1YiwgYWVzKHkgPSBsaWZlLCB4ID0gaW5jb21lcGV0aWxlLGNvbG9yID0gc3RhdGVuYW1lLCBncm91cCA9IHN0YXRlbmFtZSkpKwogIGdlb21fbGluZShzaXplID0gMSkrCiAgdGhlbWVfYncoKSsKICB0aGVtZV9lY29ub21pc3QoKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSArCiAgbGFicyh4PSJcbkhvdXNlaG9sZCBpbmNvbWUgcXVhcnRpbGUiLCAKICAgICAgIHk9IkxpZmUgZXhwZWN0YW5jeSBhdCBhZ2UgNDBcbiIsCiAgICAgICB0aXRsZSA9ICJGZW1hbGUgbGlmZSBleHBlY3RhbmN5IHZzLiBpbmNvbWVcbiIsCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogSGVhbHRoIEluZXF1YWxpdHkgUHJvamVjdCIpICsKICB0aGVtZShheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQuaXRhbGljIiwgaGp1c3QgPSAwLjUpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpCgpwMwpgYGAKCmBgYHtyLCBldmFsPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmRmNCA8LSByZWFkLmNzdigiRGF0YS9oZWFsdGhfaW5lcV9vbmxpbmVfdGFibGVfM19tYWxlLmNzdiIpCgpkZjRfMjAwMSA8LWdhdGhlcihkZjQsaW5jb21lcGV0aWxlLGxpZmUsUTE6UTQsZmFjdG9yX2tleSA9IFRSVUUpCgpkZl9zdWJfMiA8LSBkZjRfMjAwMSU+JQogIGZpbHRlcihzdGF0ZW5hbWUgJWluJSBuYW1lKQoKcDQgPC0gZ2dwbG90KGRhdGEgPSBkZl9zdWJfMiwgYWVzKHkgPSBsaWZlLCB4ID0gaW5jb21lcGV0aWxlLGNvbG9yID0gc3RhdGVuYW1lLCBncm91cCA9IHN0YXRlbmFtZSkpKwogIGdlb21fbGluZShzaXplID0gMSkrCiAgdGhlbWVfYncoKSsKICB0aGVtZV9lY29ub21pc3QoKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSArCiAgbGFicyh4PSJcbkhvdXNlaG9sZCBpbmNvbWUgcXVhcnRpbGUiLCAKICAgICAgIHk9IkxpZmUgZXhwZWN0YW5jeSBhdCBhZ2UgNDBcbiIsCiAgICAgICB0aXRsZSA9ICJNYWxlIGxpZmUgZXhwZWN0YW5jeSB2cy4gaW5jb21lXG4iLAogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IEhlYWx0aCBJbmVxdWFsaXR5IFByb2plY3QiKSArCiAgdGhlbWUoYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkLml0YWxpYyIsIGhqdXN0ID0gMC41KSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQoKcDQKYGBgCgojIEhlYWx0aCBvdXRjb21lcyBhdCB0aGUgbG9jYWwgbGV2ZWwKCmBgYHtyLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgaW5jbHVkZT1GQUxTRSwgZXZhbD1GQUxTRX0KbG93ZXI0OCA8LSBjb3VudGllcyhzZXRkaWZmKHN0YXRlLm5hbWUsIGMoIkhhd2FpaSIsICJBbGFza2EiKSksIGNsYXNzID0gInNmIikKCmxvd2VyNDgkU1RBVEVDT1VOVFlGUCA8LSBwYXN0ZTAobG93ZXI0OCRTVEFURUZQLCBsb3dlcjQ4JENPVU5UWUZQKQoKSW5jb21lIDwtcmVhZF9jc3YoIkRhdGEvSW5jb21lRGF0YS5jc3YiKQoKSW5jb21lIDwtIEluY29tZSAlPiUKICBtdXRhdGUoIFNUQVRFQ09VTlRZRlAgPSBzdHJfcGFkKGBHRU9JRGAsIDUsICJsZWZ0IiwgcGFkID0gIjAiKSwgWWVhciA9IHllYXIpCmBgYAoKIyMgRGlhYmV0ZXMKCmBgYHtyLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgZXZhbD1GQUxTRX0KRGlhYmV0ZXMgPC0gcmVhZF9jc3YoIkRhdGEvRGlhYmV0ZXNEYXRhLmNzdiIpCgpEaWFiZXRlcyA8LSBEaWFiZXRlcyAlPiUKCW11dGF0ZShTVEFURUNPVU5UWUZQID0gc3RyX3BhZChgQ291bnR5RklQU2AsIDUsICJsZWZ0IiwgcGFkID0gIjAiKSwgUGVyY2VudGFnZSA9IGFzLm51bWVyaWMoUGVyY2VudGFnZSkpCgpjb3VudHlkaWFiZXRlcyA8LSBtZXJnZShsb3dlcjQ4LCBEaWFiZXRlcywgYnkgPSAiU1RBVEVDT1VOVFlGUCIsIGR1cGxpY2F0ZUdlb21zID0gVFJVRSkKCmNvdW50eWRpYWJldGVzaW5jb21lIDwtIG1lcmdlKGNvdW50eWRpYWJldGVzLCBJbmNvbWUsIGJ5ID0gYygiU1RBVEVDT1VOVFlGUCIsICJZZWFyIiksIGR1cGxpY2F0ZUdlb21zID0gVFJVRSkgJT4lCiAgbXV0YXRlKHllYXIgPSBhcy5pbnRlZ2VyKHllYXIpKQoKY291bnR5ZGlhYmV0ZXNpbmNvbWUkYWRqdXN0ZWRyYXRlIDwtIGNvdW50eWRpYWJldGVzaW5jb21lJFBlcmNlbnRhZ2UvY291bnR5ZGlhYmV0ZXNpbmNvbWUkaW5jb21lX3Blcl9jYXBpdGEKYGBgCgpUaGlzIHBsb3QgZGVtb25zdHJhdGVzIGEgY2xlYXIgY29ycmVsYXRpb24gYmV0d2VlbiBkaWFiZXRlcyByYXRlcyBhbmQgaW5jb21lLCB3aXRoIGhpZ2hlciBpbmNvbWUgY291bnRpZXMgaGF2aW5nIGxvd2VyIHJhdGVzIG9mIGRpYWJldGVzLiBJdCBhbHNvIHNob3dzIHRoYXQgd2hpbGUgZGlhYmV0ZXMgaGFzIGluY3JlYXNlZCBldmVyeXdoZXJlIG92ZXIgdGltZSwgdGhlIGluY3JlYXNlcyBoYXZlIGJlZW4gZmFyIG1vcmUgcHJvbm91bmNlZCBmb3IgcG9vcmVyIGNvdW50aWVzLiBOb3RlIGVzcGVjaWFsbHkgdGhlIHNoYXJwIHNwaWtlIGluIHJhdGVzIG92ZXIgMjAxNS0yMDE2CgpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIGV2YWw9RkFMU0V9CmRpYWJldGVzcGxvdCA8LSBnZ3Bsb3QoZmlsdGVyKGNvdW50eWRpYWJldGVzaW5jb21lLCBpbmNvbWVfcGVyX2NhcGl0YSA8IDEwMDAwMCksIAogICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gaW5jb21lX3Blcl9jYXBpdGEsIHkgPSBQZXJjZW50YWdlLCBjb2xvciA9IHJlZ2lvbl9uYW1lKSkgKwogIGdlb21faml0dGVyKGFscGhhID0gLjcpICsKICB0aGVtZV9lY29ub21pc3QoKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSArCiAgbGFicyh4PSJcbkluY29tZSBwZXIgY2FwaXRhIiwKICAgICAgIHRpdGxlID0gIkRpYWJldGVzIHJhdGUgdnMuIGluY29tZVxuIiwKICAgICAgIGNhcHRpb24gPSAiU291cmNlOiBDREMiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IGZ1bmN0aW9uKHgpIHBhc3RlMCh4LCAiJSIpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IGRvbGxhcikgKwogIHRoZW1lKGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZC5pdGFsaWMiLCBoanVzdCA9IDAuNSksIAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpKQoKZGlhYmV0ZXNwbG90YW5pbSA8LSBkaWFiZXRlc3Bsb3QgKyB0cmFuc2l0aW9uX3RpbWUoeWVhcikgKwogIGxhYnModGl0bGUgPSAiRGlhYmV0ZXMgcmF0ZSB2cy4gaW5jb21lOiB7ZnJhbWVfdGltZX1cbiIpCgpkaWFiZXRlc3Bsb3RhbmltCmFuaW1fc2F2ZSgiZGlhYmV0ZXNwbG90YW5pbS5naWYiKQpgYGAKCiFbRGlhYmV0ZXMgJiBJbmNvbWUsIGJ5IHJlZ2lvbl0oSW1hZ2VzL2RpYWJldGVzcGxvdGFuaW0uZ2lmKQoKClRoZSBmaXJzdCBtYXAgc2hvd3MgZGlhYmV0ZXMgcmF0ZXMgYXMgYSBwZXJjZW50YWdlIG9mIHRoZSBwb3B1bGF0aW9uIGZvciBlYWNoIGNvdW50eSBpbiB0aGUgVVMuIFRoZSBzZWNvbmQgbWFwcyBhbiBhZGp1c3RlZCBtZXRyaWMsIHRoZSBkaWFiZXRlcyByYXRpby9wZXItY2FwaXRhIGluY29tZSByYXRpby4gVGhpcyBpbmNvbWUtYWRqdXN0ZWQgYWRqdWVzdGVkIHJhdGlvIGlzIGludGVuZGVkIHRvIGFjY291bnQgZm9yIHZhcmlhbmNlIGR1ZSB0byBpbmNvbWUuIEdlb2dyYXBoaWMgZGlmZmVyZW5jZXMgaW4gZGlhYmV0ZXMgcmF0ZXMgYXJlIG1vcmUgbXV0ZWQgaW4gdGhlIGFkanVzdGVkIG1hcCwgaW5kaWNhdGluZyB0aGF0IHNvbWUgb2YgdGhlIGRpZmZlcmVuY2VzIGluIGRpYWJldGVzIGxldmVscyBhcmUgYWN0dWFsbHkgdGhlIHJlc3VsdCBvZiBpbmNvbWUgY2x1c3RlcmluZy4gCgpgYGB7ciwgZXZhbCA9IEZBTFNFfQpkaWFiZXRlcyA8LSB0bV9zaGFwZShmaWx0ZXIoY291bnR5ZGlhYmV0ZXMsIFllYXIgPT0gIjIwMTYiKSkgKwogIHRtX2ZpbGwoY29sID0gIlBlcmNlbnRhZ2UiLCB0aXRsZSA9ICIiLCBwYWwgPSAiWWxPclJkIiwgbiA9IDUpICsKICB0bV9sYXlvdXQoZnJhbWUgPSBGQUxTRSwgbGVnZW5kLmZvcm1hdCA9IGxpc3QoCiAgICBmdW4gPSBmdW5jdGlvbih4KSBwYXN0ZTAoZm9ybWF0Qyh4LCBkaWdpdHMgPSAwLCBmb3JtYXQgPSAiZiIpLCAiJSIpKSkKCnRtYXBfc2F2ZShkaWFiZXRlcywgImRpYWJldGVzX2NvdW50aWVzXzIwMTZfbWFwLnBuZyIpCmBgYAohW0RpYWJldGVzIHJhdGUgYnkgY291bnR5OiAyMDE2XShJbWFnZXMvZGlhYmV0ZXNfY291bnRpZXNfMjAxNl9tYXAucG5nKQoKYGBge3IsIGV2YWwgPSBGQUxTRX0KZGlhYmV0ZXNfYWRqdXN0ZWQgPC0gdG1fc2hhcGUoZmlsdGVyKGNvdW50eWRpYWJldGVzaW5jb21lLCBZZWFyID09ICIyMDE2IikpICsKICB0bV9maWxsKGNvbCA9ICJhZGp1c3RlZHJhdGUiLCB0aXRsZSA9ICJEaWFiZXRlcy10by1cbmluY29tZSByYXRpbyIsIHBhbCA9ICJZbE9yUmQiLCBuID0gNSkgKwogIHRtX2xheW91dChmcmFtZSA9IEZBTFNFLCBsZWdlbmQuZm9ybWF0ID0gbGlzdCgKICAgIGZ1biA9IGZ1bmN0aW9uKHgpIHBhc3RlMChmb3JtYXRDKHgsIGRpZ2l0cyA9IDQsIGZvcm1hdCA9ICJmIikpKSkKCnRtYXBfc2F2ZShkaWFiZXRlc19hZGp1c3RlZCwgImRpYWJldGVzX2luY29tZV9yYXRpb19jb3VudGllc18yMDE2X21hcC5wbmciKQpgYGAKCiFbRGlhYmV0ZXMgYWRqdXN0ZWQgbWV0cmljIGJ5IGNvdW50eTogMjAxNl0oSW1hZ2VzL2RpYWJldGVzX2luY29tZV9yYXRpb19jb3VudGllc18yMDE2X21hcC5wbmcpCgoKIyMgTGlmZSBleHBlY3RhbmN5CgpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIGV2YWw9RkFMU0V9CkxpZmVFeHAgPC0gcmVhZF9jc3YoIkRhdGEvRXhwZWN0YW5jeURhdGEuY3N2IikKCkxpZmVFeHAgPC0gTGlmZUV4cCAlPiUKICBtdXRhdGUoY2xlYW5fbGlmZWV4cCA9IGFzLm51bWVyaWMoc3RyX2V4dHJhY3QoYExpZmUgZXhwZWN0YW5jeWAsICJeXFxkKi5cXGQqIikpLCAKICAgICAgICAgU1RBVEVDT1VOVFlGUCA9IHN0cl9wYWQoYEZJUFNgLCA1LCAibGVmdCIsIHBhZCA9ICIwIikpCgpjb3VudHlsaWZlIDwtIG1lcmdlKGxvd2VyNDgsIExpZmVFeHAsIGJ5ID0gIlNUQVRFQ09VTlRZRlAiLCBkdXBsaWNhdGVHZW9tcyA9IFRSVUUpCgpjb3VudHlsaWZlaW5jb21lIDwtIG1lcmdlKGNvdW50eWxpZmUsIEluY29tZSwgYnkgPSBjKCJTVEFURUNPVU5UWUZQIiwgIlllYXIiKSwgZHVwbGljYXRlR2VvbXMgPSBUUlVFKSAlPiUKICBtdXRhdGUoeWVhciA9IGFzLmludGVnZXIoeWVhcikpCgpjb3VudHlsaWZlaW5jb21lJGFkanVzdGVkcmF0ZSA8LSBjb3VudHlsaWZlaW5jb21lJGNsZWFuX2xpZmVleHAvY291bnR5bGlmZWluY29tZSRpbmNvbWVfcGVyX2NhcGl0YQpgYGAKClRoaXMgcGxvdCBkZW1vbnN0cmF0ZXMgYSBjbGVhciByZWxhdGlub3NoaXAgYmV0d2VlbiBsaWZlIGV4cGVjdGFuY3kgYW5kIGluY29tZSwgd2l0aCBoaWdoZXIgaW5jb21lIGNvdW50aWVzIGhhdmluZyBoaWdoZXIgYXZlcmFnZSBsaWZlIGV4cGVjdGFuY3kuIFRoZXJlIGlzIGEgd29ycnlpbmcgcGF0dGVybiBvZiBsaWZlIGV4cGVjdGFuY3kgaW5jcmVhc2luZyBmb3IgaGlnaGVyLWluY29tZSBjb3VudGllcyB3aGlsZSBsaWZlIGV4cGVjdGFuY3kgaXMgY29uc3RhbnQgb3IgZmFsbGluZyBpbiBsb3dlci1pbmNvbWUgY291bnRpZXMuIAoKYGBge3IsIGV2YWwgPSBGQUxTRX0KbGlmZXBsb3QgPC0gZ2dwbG90KGZpbHRlcihjb3VudHlsaWZlaW5jb21lLCBpbmNvbWVfcGVyX2NhcGl0YSA8IDEwMDAwMCksIAogICAgICAgICAgICAgICAgICAgYWVzKHggPSBpbmNvbWVfcGVyX2NhcGl0YSwgeSA9IGNsZWFuX2xpZmVleHAsIGNvbG9yID0gcmVnaW9uX25hbWUpKSArCiAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAuNykgKwogIHRoZW1lX2Vjb25vbWlzdCgpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpICsKICBsYWJzKHg9IlxuSW5jb21lIHBlciBjYXBpdGEiLAogICAgICAgdGl0bGUgPSAiTGlmZSBleHBlY3RhbmN5IHZzLiBpbmNvbWVcbiIsCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogSUhNRSIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gZG9sbGFyKSArCiAgdGhlbWUoYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkLml0YWxpYyIsIGhqdXN0ID0gMC41KSwgCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCkpCgpsaWZlcGxvdGFuaW0gPC0gbGlmZXBsb3QgKyB0cmFuc2l0aW9uX3RpbWUoeWVhcikgKwogIGxhYnModGl0bGUgPSAiTGlmZSBleHBlY3RhbmN5IHZzLiBpbmNvbWU6IHtmcmFtZV90aW1lfSIpCmxpZmVwbG90YW5pbQphbmltX3NhdmUoImxpZmVwbG90YW5pbS5naWYiKQpgYGAKCiFbTGlmZSBFeHBlY3RhbmN5ICYgSW5jb21lLCBieSByZWdpb25dKEltYWdlcy9saWZlcGxvdGFuaW0uZ2lmKQoKClRoZSBmaXJzdCBtYXAgc2hvd3MgbGlmZSBleHBlY3RhbmN5IGZvciBlYWNoIGNvdW50eSBpbiB0aGUgVVMuIFRoZSBzZWNvbmQgbWFwcyBhbiBhZGp1c3RlZCBtZXRyaWMsIGxpZmUgZXhwZWN0YW5jeS9pbmNvbWUgcGVyIGNhcGl0YS4gR2VvZ3JhcGhpYyBkaWZmZXJlbmNlcyBpbiBsaWZlIGV4cGVjdGFuY3kgKGludGVuc2l0eSBvZiBjb2xvciB2YXJpYXRpb24pIGFyZSBzaWduaWZpY2FudGx5IG1vcmUgbXV0ZWQgaW4gdGhlIGFkanVzdGVkIG1hcCwgaW5kaWNhdGluZyB0aGF0IG11Y2ggb2YgdGhlIHZhcmlhbmNlIGluIGxpZmUgZXhwZWN0YW5jeSBpcyB0aGUgcmVzdWx0IG9mIGluY29tZSBjbHVzdGVyaW5nLiBUaGUgcG9vciBjb3VudGllcyBleHBlcmllbmNpbmcgZGVjcmVhc2luZyBsaWZlIGV4cGVjdGFuY3kgYXJlIGxhcmdlbHkgaW4gdGhlIFNvdXRoIGFuZCBNaWR3ZXN0LgoKIyMgUmVndWxhciBtYXAKCmBgYHtyLCBldmFsID0gRkFMU0V9CmxpZmVfZXhwZWN0YW5jeSA8LSB0bV9zaGFwZShmaWx0ZXIoY291bnR5bGlmZSwgWWVhciA9PSAiMjAxNCIpKSArCiAgdG1fZmlsbChjb2wgPSAiY2xlYW5fbGlmZWV4cCIsIHRpdGxlID0gIiIsIHBhbCA9ICJZbEduIiwgbiA9IDUpICsKICB0bV9sYXlvdXQoZnJhbWUgPSBGQUxTRSwgbGVnZW5kLmZvcm1hdCA9IGxpc3QoCiAgICBmdW4gPSBmdW5jdGlvbih4KSBwYXN0ZTAoZm9ybWF0Qyh4LCBkaWdpdHMgPSAwLCBmb3JtYXQgPSAiZiIpKSkpCgp0bWFwX3NhdmUobGlmZV9leHBlY3RhbmN5LCAibGlmZV9leHBlY3RhbmN5X2NvdW50aWVzXzIwMTRfbWFwLnBuZyIpCmBgYAohW0xpZmUgZXhwZWN0YW5jeSBieSBjb3VudHk6IDIwMTRdKEltYWdlcy9saWZlX2V4cGVjdGFuY3lfY291bnRpZXNfMjAxNF9tYXAucG5nKQoKCmBgYHtyLCBldmFsID0gRkFMU0V9CmxpZmVfZXhwZWN0YW5jeV9hZGp1c3RlZCA8LSB0bV9zaGFwZShmaWx0ZXIoY291bnR5bGlmZWluY29tZSwgWWVhciA9PSAiMjAxNCIpKSArCiAgdG1fZmlsbChjb2wgPSAiYWRqdXN0ZWRyYXRlIiwgdGl0bGUgPSAiTGlmZSBleHBlY3RhbmN5LXRvLVxuaW5jb21lIHJhdGlvIiwgcGFsID0gIllsR24iLCBuID0gNSkgKwogIHRtX2xheW91dChmcmFtZSA9IEZBTFNFLCBsZWdlbmQuZm9ybWF0ID0gbGlzdCgKICAgIGZ1biA9IGZ1bmN0aW9uKHgpIHBhc3RlMChmb3JtYXRDKHgsIGRpZ2l0cyA9IDMsIGZvcm1hdCA9ICJmIikpKSkKCnRtYXBfc2F2ZShsaWZlX2V4cGVjdGFuY3lfYWRqdXN0ZWQsICJsaWZlX2V4cGVjdGFuY3lfYWRqdXN0ZWRfY291bnRpZXNfMjAxNF9tYXAucG5nIikKYGBgCiFbTGlmZSBleHBlY3RhbmN5IGFkanVzdGVkIG1ldHJpYyBieSBjb3VudHk6IDIwMTRdKEltYWdlcy9saWZlX2V4cGVjdGFuY3lfYWRqdXN0ZWRfY291bnRpZXNfMjAxNF9tYXAucG5nKQoKCiMjIEluZmFudCBtb3J0YWxpdHkgCgpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIGV2YWw9RkFMU0V9CmltX2RhdGEgPC0gcmVhZF9leGNlbCgiRGF0YS9MaW5rZWRfQmlydGhfSW5mYW50X0RlYXRoX1JlY29yZHNfcGVyXzEwMDBfYnlfQ291bnR5X2FuZF9ZZWFyX0RpZWRfMjAwNy0yMDE3Lnhsc3giKQoKaW1fZGF0YSA8LSBpbV9kYXRhICU+JQogIG11dGF0ZShTVEFURUNPVU5UWUZQID0gc3RyX3BhZChgQ291bnR5IENvZGVgLCA1LCAibGVmdCIsIHBhZCA9ICIwIiksIAogICAgICAgICBEZWF0aHJhdGUgPSBhcy5udW1lcmljKGBEZWF0aCBSYXRlYCkpCgpjb3VudHlpbmZhbnQgPC0gbWVyZ2UobG93ZXI0OCwgaW1fZGF0YSwgYnkgPSAiU1RBVEVDT1VOVFlGUCIsIGR1cGxpY2F0ZUdlb21zID0gVFJVRSkKCmNvdW50eWluZmFudGluY29tZSA8LSBtZXJnZShpbV9kYXRhLCBJbmNvbWUsIGJ5ID0gIlNUQVRFQ09VTlRZRlAiLCBkdXBsaWNhdGVHZW9tcyA9IFRSVUUpICU+JQogIG11dGF0ZSh5ZWFyID0gYXMuaW50ZWdlcih5ZWFyKSkKCmNvdW50eWluZmFudGluY29tZSRhZGp1c3RlZHJhdGUgPC0gY291bnR5aW5mYW50aW5jb21lJERlYXRocmF0ZS9jb3VudHlpbmZhbnRpbmNvbWUkaW5jb21lX3Blcl9jYXBpdGEKYGBgCgpJbmZhbnQgbW9ydGFsaXR5IHNob3dzIGEgY2xlYXIgY29ycmVsYXRpb24gdG8gaW5jb21lLCB3aXRoIGhpZ2hlciBpbmNvbWUgY291bnRpZXMgaGF2aW5nIGxvd2VyIGluZmFudCBtb3J0YWxpdHkuIE5laXRoZXIgdGhlIHBhdHRlcm4gbm9yIHRoZSBvdmVyYWxsIGluY2lkZW5jZSBvZiBjaGlsZCBtb3J0YWxpdHkgYXBwZWFycyB0byBiZSBjaGFuZ2luZy4KCmBgYHtyLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgZXZhbD1GQUxTRX0KaW5mYW50cGxvdCA8LSBnZ3Bsb3QoZmlsdGVyKGNvdW50eWluZmFudGluY29tZSwgaW5jb21lX3Blcl9jYXBpdGEgPCAxMDAwMDApLCAKICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBpbmNvbWVfcGVyX2NhcGl0YSwgeSA9IERlYXRocmF0ZSwgY29sb3IgPSByZWdpb25fbmFtZSkpICsKICBnZW9tX2ppdHRlcihhbHBoYSA9IC43KSArCiAgdGhlbWVfZWNvbm9taXN0KCkgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikgKwogIGxhYnMoeD0iXG5JbmNvbWUgcGVyIGNhcGl0YSIsCiAgICAgICB5ID0gIkRlYXRocyBwZXIgMSwwMDAgbGl2ZSBiaXJ0aHNcbiIsCiAgICAgICB0aXRsZSA9ICJJbmZhbnQgbW9ydGFsaXR5IHZzLiBpbmNvbWVcbiIsCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogQ0RDIikgKwogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBkb2xsYXIpICsKICB0aGVtZShheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQuaXRhbGljIiwgaGp1c3QgPSAwLjUpLCAKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQoKaW5mYW50cGxvdGFuaW0gPC0gaW5mYW50cGxvdCArIHRyYW5zaXRpb25fdGltZSh5ZWFyKSArCiAgbGFicyh0aXRsZSA9ICJJbmZhbnQgbW9ydGFsaXR5IHZzLiBpbmNvbWU6IHtmcmFtZV90aW1lfSIpCmluZmFudHBsb3RhbmltCmFuaW1fc2F2ZSgiaW5mYW50cGxvdGFuaW0uZ2lmIikKYGBgCgohW0luZmFudCBtb3J0YWxpdHkgJiBJbmNvbWUsIGJ5IHJlZ2lvbl0oSW1hZ2VzL2luZmFudHBsb3RhbmltLmdpZikKCgoKIyBIZWFsdGggaW5zdXJhbmNlCgpJbiB0aGlzIHNlY3Rpb24sIHdlIGFpbSB0byBmdXJ0aGVyIG91ciBpbnZlc3RpZ2F0aW9uIG9mIGluY29tZSBhbmQgaGVhbHRoIG91dGNvbWVzIGJ5IGFkZGluZyBpbiB0aGUgbWFqb3IgcGxheWVyIGluIHRoaXMgbGlua2FnZSAtLSBoZWFsdGhjYXJlIGluc3VyYW5jZS4gU3BlY2lmaWNhbGx5LCB3ZSBmb2N1cyBvbiB0aGUgdW5pbnN1cmVkIHBvcHVsYXRpb24gYW5kIGFpbSB0byB1c2UgdmlzdWFsaXphdGlvbnMgdG8gc2hvd2Nhc2UgdGhlIGluZmx1ZW5jZSBvZiBpbmNvbWUgb24gdW5pbnN1cmFuY2UgcmF0ZS4gCgpPdXIgYmFzZSBkYXRhIGNhbWUgZnJvbSB0aGUgU21hbGwgQXJlYSBIZWFsdGggSW5zdXJhbmNlIEVzdGltYXRlcyAoU0FISUUpIGZyb20gdGhlIENlbnN1cyBCdXJlYXUsIHdoaWNoIHdhcyBleHRyYWN0ZWQgZnJvbSB0aGUgQW1lcmljYW4gQ29tbXVuaXR5IFN1cnZleSAoQUNTKSBjb25kdWN0ZWQgeWVhcmx5LiBXZSBuYXJyb3dlZCBvdXIgZm9jdXMgb24gdGhlIHBlcmlvZCBvZiAyMDA4IHRvIDIwMTggZm9yIGRhdGEgY29tcGxldGVuZXNzIGFuZCBjb25zaXN0ZW5jeSBjb25zaWRlcmF0aW9ucy4gV2UgYmVsaWV2ZSB0aGUgdXNhZ2Ugb2YgYXMgcmVjZW50IGFzIHBvc3NpYmxlIGRhdGEgd291bGQgYmUgbW9zdCBpZGVhbCAoZm9yIHdoaWNoIHRoZSBsYXRlc3QgcG9zc2libGUgd2FzIHllYXIgMjAxOCksIGFuZCB3ZSBhaW1lZCB0byBoYXZlIGEgbG9uZyBlbm91Z2ggcGVyaW9kIHRvIGRldGVjdC9zaG93Y2FzZSBhbnkgdHJlbmRzLiBXZSBiZWxpZXZlIDEwIHllYXJzIGlzIGEgZ29vZCB0aW1lIGZyYW1lLiBXZSBhbHNvIGhlcmVieSBub3RlIHRoYXQgdGhlIFNBSElFIG9ubHkgc3RhcnRlZCB0byB1dGlsaXplIHRoZSBBQ1MgYXMgdGhlIGJhc2lzIGZvciBpdHMgZXN0aW1hdGVzIGluIDIwMDgsIHByaW9yIHRvIHdoaWNoIGl0IHVzZWQgdGhlIEFubnVhbCBTb2NpYWwgYW5kIEVjb25vbWljIFN1cHBsZW1lbnQgdG8gdGhlIEN1cnJlbnQgUG9wdWxhdGlvbiBTdXJ2ZXkgKENQUyBBU0VDKS4KCk5vdGU6IFRoZSBkZWZpbml0aW9uIG9mIGhlYWx0aCBpbnN1cmFuY2UgY292ZXJhZ2UgaW4gdGhlIEFDUyBpcyAtICJJcyB0aGlzIHBlcnNvbiAqKkNVUlJFTlRMWSoqIGNvdmVyZWQgYnkgW3NwZWNpZmljYWxseSBzdGF0ZWRdIGhlYWx0aCBpbnN1cmFuY2Ugb3IgaGVhbHRoIGNvdmVyYWdlIHBsYW5zPyIKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIExvYWRpbmcgZGF0YQoKc2FoaWVfMjAwOCA8LSByZWFkLmNzdigiRGF0YS9zYWhpZV8yMDA4X0ZJUFMuY3N2IiwgaGVhZGVyID0gVFJVRSkKc2FoaWVfMjAwOSA8LSByZWFkLmNzdigiRGF0YS9zYWhpZV8yMDA5X0ZJUFMuY3N2IiwgaGVhZGVyID0gVFJVRSkKc2FoaWVfMjAxMCA8LSByZWFkLmNzdigiRGF0YS9zYWhpZV8yMDEwX0ZJUFMuY3N2IiwgaGVhZGVyID0gVFJVRSkKc2FoaWVfMjAxMSA8LSByZWFkLmNzdigiRGF0YS9zYWhpZV8yMDExX0ZJUFMuY3N2IiwgaGVhZGVyID0gVFJVRSkKc2FoaWVfMjAxMiA8LSByZWFkLmNzdigiRGF0YS9zYWhpZV8yMDEyX0ZJUFMuY3N2IiwgaGVhZGVyID0gVFJVRSkKc2FoaWVfMjAxMyA8LSByZWFkLmNzdigiRGF0YS9zYWhpZV8yMDEzX0ZJUFMuY3N2IiwgaGVhZGVyID0gVFJVRSkKc2FoaWVfMjAxNCA8LSByZWFkLmNzdigiRGF0YS9zYWhpZV8yMDE0X0ZJUFMuY3N2IiwgaGVhZGVyID0gVFJVRSkKc2FoaWVfMjAxNSA8LSByZWFkLmNzdigiRGF0YS9zYWhpZV8yMDE1X0ZJUFMuY3N2IiwgaGVhZGVyID0gVFJVRSkKc2FoaWVfMjAxNiA8LSByZWFkLmNzdigiRGF0YS9zYWhpZV8yMDE2X0ZJUFMuY3N2IiwgaGVhZGVyID0gVFJVRSkKc2FoaWVfMjAxNyA8LSByZWFkLmNzdigiRGF0YS9zYWhpZV8yMDE3X0ZJUFMuY3N2IiwgaGVhZGVyID0gVFJVRSkKc2FoaWVfMjAxOCA8LSByZWFkLmNzdigiRGF0YS9zYWhpZV8yMDE4X0ZJUFMuY3N2IiwgaGVhZGVyID0gVFJVRSkKYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0KIyBDbGVhbmluZyBkYXRhCnNhaGllXzIwMDggPC0gc2FoaWVfMjAwOCAlPiUgCiAgc2VsZWN0KHllYXIsYWdlY2F0LHJhY2VjYXQsc2V4Y2F0LGlwcmNhdCxOSVBSLE5VSSxOSUMsUENUVUksUENUSUMsUENURUxJRyxQQ1RMSUlDLAogICAgICAgICBzdGF0ZV9uYW1lLCBjb3VudHlfbmFtZSwgZmlwcykgJT4lCiAgbXV0YXRlKE5JUFI9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOSVBSKSkpKSwKICAgICAgICAgTlVJPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTlVJKSkpKSwKICAgICAgICAgTklDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTklDKSkpKSwKICAgICAgICAgUENUVUk9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RVSSkpKSksCiAgICAgICAgIFBDVElDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUSUMpKSkpLAogICAgICAgICBQQ1RFTElHPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENURUxJRykpKSksCiAgICAgICAgIFBDVExJSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RMSUlDKSkpKSwKICAgICAgICAgc3RhdGVfbmFtZT10cmltd3MoYXMuY2hhcmFjdGVyKHN0YXRlX25hbWUpKSxjb3VudHlfbmFtZT10cmltd3MoYXMuY2hhcmFjdGVyKGNvdW50eV9uYW1lKSkpICU+JQogIG11dGF0ZShmaXBzID0gaWZlbHNlKHN0cl9sZW5ndGgoZmlwcykgPCA1LCBwYXN0ZTAoMCwgZmlwcyksIGZpcHMpKQpzYWhpZV8yMDA5IDwtIHNhaGllXzIwMDkgJT4lIAogIHNlbGVjdCh5ZWFyLGFnZWNhdCxyYWNlY2F0LHNleGNhdCxpcHJjYXQsTklQUixOVUksTklDLFBDVFVJLFBDVElDLFBDVEVMSUcsUENUTElJQywKICAgICAgICAgc3RhdGVfbmFtZSwgY291bnR5X25hbWUsIGZpcHMpICU+JQogIG11dGF0ZShOSVBSPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTklQUikpKSksCiAgICAgICAgIE5VST1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5VSSkpKSksCiAgICAgICAgIE5JQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5JQykpKSksCiAgICAgICAgIFBDVFVJPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUVUkpKSkpLAogICAgICAgICBQQ1RJQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVElDKSkpKSwKICAgICAgICAgUENURUxJRz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVEVMSUcpKSkpLAogICAgICAgICBQQ1RMSUlDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUTElJQykpKSksCiAgICAgICAgIHN0YXRlX25hbWU9dHJpbXdzKGFzLmNoYXJhY3RlcihzdGF0ZV9uYW1lKSksY291bnR5X25hbWU9dHJpbXdzKGFzLmNoYXJhY3Rlcihjb3VudHlfbmFtZSkpKSAlPiUKICBtdXRhdGUoZmlwcyA9IGlmZWxzZShzdHJfbGVuZ3RoKGZpcHMpIDwgNSwgcGFzdGUwKDAsIGZpcHMpLCBmaXBzKSkKc2FoaWVfMjAxMCA8LSBzYWhpZV8yMDEwICU+JSAKICBzZWxlY3QoeWVhcixhZ2VjYXQscmFjZWNhdCxzZXhjYXQsaXByY2F0LE5JUFIsTlVJLE5JQyxQQ1RVSSxQQ1RJQyxQQ1RFTElHLFBDVExJSUMsCiAgICAgICAgIHN0YXRlX25hbWUsIGNvdW50eV9uYW1lLCBmaXBzKSAlPiUKICBtdXRhdGUoTklQUj1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5JUFIpKSkpLAogICAgICAgICBOVUk9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOVUkpKSkpLAogICAgICAgICBOSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOSUMpKSkpLAogICAgICAgICBQQ1RVST1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVFVJKSkpKSwKICAgICAgICAgUENUSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RJQykpKSksCiAgICAgICAgIFBDVEVMSUc9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RFTElHKSkpKSwKICAgICAgICAgUENUTElJQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVExJSUMpKSkpLAogICAgICAgICBzdGF0ZV9uYW1lPXRyaW13cyhhcy5jaGFyYWN0ZXIoc3RhdGVfbmFtZSkpLGNvdW50eV9uYW1lPXRyaW13cyhhcy5jaGFyYWN0ZXIoY291bnR5X25hbWUpKSkgJT4lCiAgbXV0YXRlKGZpcHMgPSBpZmVsc2Uoc3RyX2xlbmd0aChmaXBzKSA8IDUsIHBhc3RlMCgwLCBmaXBzKSwgZmlwcykpCnNhaGllXzIwMTEgPC0gc2FoaWVfMjAxMSAlPiUgCiAgc2VsZWN0KHllYXIsYWdlY2F0LHJhY2VjYXQsc2V4Y2F0LGlwcmNhdCxOSVBSLE5VSSxOSUMsUENUVUksUENUSUMsUENURUxJRyxQQ1RMSUlDLAogICAgICAgICBzdGF0ZV9uYW1lLCBjb3VudHlfbmFtZSwgZmlwcykgJT4lCiAgbXV0YXRlKE5JUFI9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOSVBSKSkpKSwKICAgICAgICAgTlVJPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTlVJKSkpKSwKICAgICAgICAgTklDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTklDKSkpKSwKICAgICAgICAgUENUVUk9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RVSSkpKSksCiAgICAgICAgIFBDVElDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUSUMpKSkpLAogICAgICAgICBQQ1RFTElHPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENURUxJRykpKSksCiAgICAgICAgIFBDVExJSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RMSUlDKSkpKSwKICAgICAgICAgc3RhdGVfbmFtZT10cmltd3MoYXMuY2hhcmFjdGVyKHN0YXRlX25hbWUpKSxjb3VudHlfbmFtZT10cmltd3MoYXMuY2hhcmFjdGVyKGNvdW50eV9uYW1lKSkpICU+JQogIG11dGF0ZShmaXBzID0gaWZlbHNlKHN0cl9sZW5ndGgoZmlwcykgPCA1LCBwYXN0ZTAoMCwgZmlwcyksIGZpcHMpKQpzYWhpZV8yMDEyIDwtIHNhaGllXzIwMTIgJT4lIAogIHNlbGVjdCh5ZWFyLGFnZWNhdCxyYWNlY2F0LHNleGNhdCxpcHJjYXQsTklQUixOVUksTklDLFBDVFVJLFBDVElDLFBDVEVMSUcsUENUTElJQywKICAgICAgICAgc3RhdGVfbmFtZSwgY291bnR5X25hbWUsIGZpcHMpICU+JQogIG11dGF0ZShOSVBSPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTklQUikpKSksCiAgICAgICAgIE5VST1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5VSSkpKSksCiAgICAgICAgIE5JQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5JQykpKSksCiAgICAgICAgIFBDVFVJPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUVUkpKSkpLAogICAgICAgICBQQ1RJQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVElDKSkpKSwKICAgICAgICAgUENURUxJRz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVEVMSUcpKSkpLAogICAgICAgICBQQ1RMSUlDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUTElJQykpKSksCiAgICAgICAgIHN0YXRlX25hbWU9dHJpbXdzKGFzLmNoYXJhY3RlcihzdGF0ZV9uYW1lKSksY291bnR5X25hbWU9dHJpbXdzKGFzLmNoYXJhY3Rlcihjb3VudHlfbmFtZSkpKSAlPiUKICBtdXRhdGUoZmlwcyA9IGlmZWxzZShzdHJfbGVuZ3RoKGZpcHMpIDwgNSwgcGFzdGUwKDAsIGZpcHMpLCBmaXBzKSkKc2FoaWVfMjAxMyA8LSBzYWhpZV8yMDEzICU+JSAKICBzZWxlY3QoeWVhcixhZ2VjYXQscmFjZWNhdCxzZXhjYXQsaXByY2F0LE5JUFIsTlVJLE5JQyxQQ1RVSSxQQ1RJQyxQQ1RFTElHLFBDVExJSUMsCiAgICAgICAgIHN0YXRlX25hbWUsIGNvdW50eV9uYW1lLCBmaXBzKSAlPiUKICBtdXRhdGUoTklQUj1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5JUFIpKSkpLAogICAgICAgICBOVUk9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOVUkpKSkpLAogICAgICAgICBOSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOSUMpKSkpLAogICAgICAgICBQQ1RVST1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVFVJKSkpKSwKICAgICAgICAgUENUSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RJQykpKSksCiAgICAgICAgIFBDVEVMSUc9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RFTElHKSkpKSwKICAgICAgICAgUENUTElJQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVExJSUMpKSkpLAogICAgICAgICBzdGF0ZV9uYW1lPXRyaW13cyhhcy5jaGFyYWN0ZXIoc3RhdGVfbmFtZSkpLGNvdW50eV9uYW1lPXRyaW13cyhhcy5jaGFyYWN0ZXIoY291bnR5X25hbWUpKSkgJT4lCiAgbXV0YXRlKGZpcHMgPSBpZmVsc2Uoc3RyX2xlbmd0aChmaXBzKSA8IDUsIHBhc3RlMCgwLCBmaXBzKSwgZmlwcykpCnNhaGllXzIwMTQgPC0gc2FoaWVfMjAxNCAlPiUgCiAgc2VsZWN0KHllYXIsYWdlY2F0LHJhY2VjYXQsc2V4Y2F0LGlwcmNhdCxOSVBSLE5VSSxOSUMsUENUVUksUENUSUMsUENURUxJRyxQQ1RMSUlDLAogICAgICAgICBzdGF0ZV9uYW1lLCBjb3VudHlfbmFtZSwgZmlwcykgJT4lCiAgbXV0YXRlKE5JUFI9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOSVBSKSkpKSwKICAgICAgICAgTlVJPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTlVJKSkpKSwKICAgICAgICAgTklDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTklDKSkpKSwKICAgICAgICAgUENUVUk9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RVSSkpKSksCiAgICAgICAgIFBDVElDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUSUMpKSkpLAogICAgICAgICBQQ1RFTElHPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENURUxJRykpKSksCiAgICAgICAgIFBDVExJSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RMSUlDKSkpKSwKICAgICAgICAgc3RhdGVfbmFtZT10cmltd3MoYXMuY2hhcmFjdGVyKHN0YXRlX25hbWUpKSxjb3VudHlfbmFtZT10cmltd3MoYXMuY2hhcmFjdGVyKGNvdW50eV9uYW1lKSkpICU+JQogIG11dGF0ZShmaXBzID0gaWZlbHNlKHN0cl9sZW5ndGgoZmlwcykgPCA1LCBwYXN0ZTAoMCwgZmlwcyksIGZpcHMpKQpzYWhpZV8yMDE1IDwtIHNhaGllXzIwMTUgJT4lIAogIHNlbGVjdCh5ZWFyLGFnZWNhdCxyYWNlY2F0LHNleGNhdCxpcHJjYXQsTklQUixOVUksTklDLFBDVFVJLFBDVElDLFBDVEVMSUcsUENUTElJQywKICAgICAgICAgc3RhdGVfbmFtZSwgY291bnR5X25hbWUsIGZpcHMpICU+JQogIG11dGF0ZShOSVBSPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTklQUikpKSksCiAgICAgICAgIE5VST1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5VSSkpKSksCiAgICAgICAgIE5JQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5JQykpKSksCiAgICAgICAgIFBDVFVJPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUVUkpKSkpLAogICAgICAgICBQQ1RJQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVElDKSkpKSwKICAgICAgICAgUENURUxJRz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVEVMSUcpKSkpLAogICAgICAgICBQQ1RMSUlDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUTElJQykpKSksCiAgICAgICAgIHN0YXRlX25hbWU9dHJpbXdzKGFzLmNoYXJhY3RlcihzdGF0ZV9uYW1lKSksY291bnR5X25hbWU9dHJpbXdzKGFzLmNoYXJhY3Rlcihjb3VudHlfbmFtZSkpKSAlPiUKICBtdXRhdGUoZmlwcyA9IGlmZWxzZShzdHJfbGVuZ3RoKGZpcHMpIDwgNSwgcGFzdGUwKDAsIGZpcHMpLCBmaXBzKSkKc2FoaWVfMjAxNiA8LSBzYWhpZV8yMDE2ICU+JSAKICBzZWxlY3QoeWVhcixhZ2VjYXQscmFjZWNhdCxzZXhjYXQsaXByY2F0LE5JUFIsTlVJLE5JQyxQQ1RVSSxQQ1RJQyxQQ1RFTElHLFBDVExJSUMsCiAgICAgICAgIHN0YXRlX25hbWUsIGNvdW50eV9uYW1lLCBmaXBzKSAlPiUKICBtdXRhdGUoTklQUj1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5JUFIpKSkpLAogICAgICAgICBOVUk9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOVUkpKSkpLAogICAgICAgICBOSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOSUMpKSkpLAogICAgICAgICBQQ1RVST1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVFVJKSkpKSwKICAgICAgICAgUENUSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RJQykpKSksCiAgICAgICAgIFBDVEVMSUc9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RFTElHKSkpKSwKICAgICAgICAgUENUTElJQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVExJSUMpKSkpLAogICAgICAgICBzdGF0ZV9uYW1lPXRyaW13cyhhcy5jaGFyYWN0ZXIoc3RhdGVfbmFtZSkpLGNvdW50eV9uYW1lPXRyaW13cyhhcy5jaGFyYWN0ZXIoY291bnR5X25hbWUpKSkgJT4lCiAgbXV0YXRlKGZpcHMgPSBpZmVsc2Uoc3RyX2xlbmd0aChmaXBzKSA8IDUsIHBhc3RlMCgwLCBmaXBzKSwgZmlwcykpCnNhaGllXzIwMTcgPC0gc2FoaWVfMjAxNyAlPiUgCiAgc2VsZWN0KHllYXIsYWdlY2F0LHJhY2VjYXQsc2V4Y2F0LGlwcmNhdCxOSVBSLE5VSSxOSUMsUENUVUksUENUSUMsUENURUxJRyxQQ1RMSUlDLAogICAgICAgICBzdGF0ZV9uYW1lLCBjb3VudHlfbmFtZSwgZmlwcykgJT4lCiAgbXV0YXRlKE5JUFI9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgICAgIC4iLCIiLGFzLmNoYXJhY3RlcihOSVBSKSkpKSwKICAgICAgICAgTlVJPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTlVJKSkpKSwKICAgICAgICAgTklDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTklDKSkpKSwKICAgICAgICAgUENUVUk9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RVSSkpKSksCiAgICAgICAgIFBDVElDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUSUMpKSkpLAogICAgICAgICBQQ1RFTElHPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENURUxJRykpKSksCiAgICAgICAgIFBDVExJSUM9YXMubnVtZXJpYyh0cmltd3MoZ3N1YigiICAgLiAiLCIiLGFzLmNoYXJhY3RlcihQQ1RMSUlDKSkpKSwKICAgICAgICAgc3RhdGVfbmFtZT10cmltd3MoYXMuY2hhcmFjdGVyKHN0YXRlX25hbWUpKSxjb3VudHlfbmFtZT10cmltd3MoYXMuY2hhcmFjdGVyKGNvdW50eV9uYW1lKSkpICU+JQogIG11dGF0ZShmaXBzID0gaWZlbHNlKHN0cl9sZW5ndGgoZmlwcykgPCA1LCBwYXN0ZTAoMCwgZmlwcyksIGZpcHMpKQpzYWhpZV8yMDE4IDwtIHNhaGllXzIwMTggJT4lIAogIHNlbGVjdCh5ZWFyLGFnZWNhdCxyYWNlY2F0LHNleGNhdCxpcHJjYXQsTklQUixOVUksTklDLFBDVFVJLFBDVElDLFBDVEVMSUcsUENUTElJQywKICAgICAgICAgc3RhdGVfbmFtZSwgY291bnR5X25hbWUsIGZpcHMpICU+JQogIG11dGF0ZShOSVBSPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgICAgICAuIiwiIixhcy5jaGFyYWN0ZXIoTklQUikpKSksCiAgICAgICAgIE5VST1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5VSSkpKSksCiAgICAgICAgIE5JQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAgICAgLiIsIiIsYXMuY2hhcmFjdGVyKE5JQykpKSksCiAgICAgICAgIFBDVFVJPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUVUkpKSkpLAogICAgICAgICBQQ1RJQz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVElDKSkpKSwKICAgICAgICAgUENURUxJRz1hcy5udW1lcmljKHRyaW13cyhnc3ViKCIgICAuICIsIiIsYXMuY2hhcmFjdGVyKFBDVEVMSUcpKSkpLAogICAgICAgICBQQ1RMSUlDPWFzLm51bWVyaWModHJpbXdzKGdzdWIoIiAgIC4gIiwiIixhcy5jaGFyYWN0ZXIoUENUTElJQykpKSksCiAgICAgICAgIHN0YXRlX25hbWU9dHJpbXdzKGFzLmNoYXJhY3RlcihzdGF0ZV9uYW1lKSksY291bnR5X25hbWU9dHJpbXdzKGFzLmNoYXJhY3Rlcihjb3VudHlfbmFtZSkpKSAlPiUKICBtdXRhdGUoZmlwcyA9IGlmZWxzZShzdHJfbGVuZ3RoKGZpcHMpIDwgNSwgcGFzdGUwKDAsIGZpcHMpLCBmaXBzKSkKYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0KIyBPcmdhbml6ZSBieSBjb3VudGllcwoKY291bnR5XzIwMDggPC0gc2FoaWVfMjAwOCAlPiUgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSAhPSAiIikKY291bnR5XzIwMDkgPC0gc2FoaWVfMjAwOSAlPiUgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSAhPSAiIikKY291bnR5XzIwMTAgPC0gc2FoaWVfMjAxMCAlPiUgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSAhPSAiIikKY291bnR5XzIwMTEgPC0gc2FoaWVfMjAxMSAlPiUgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSAhPSAiIikKY291bnR5XzIwMTIgPC0gc2FoaWVfMjAxMiAlPiUgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSAhPSAiIikKY291bnR5XzIwMTMgPC0gc2FoaWVfMjAxMyAlPiUgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSAhPSAiIikKY291bnR5XzIwMTQgPC0gc2FoaWVfMjAxNCAlPiUgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSAhPSAiIikKY291bnR5XzIwMTUgPC0gc2FoaWVfMjAxNSAlPiUgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSAhPSAiIikKY291bnR5XzIwMTYgPC0gc2FoaWVfMjAxNiAlPiUgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSAhPSAiIikKY291bnR5XzIwMTcgPC0gc2FoaWVfMjAxNyAlPiUgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSAhPSAiIikKY291bnR5XzIwMTggPC0gc2FoaWVfMjAxOCAlPiUgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSAhPSAiIikKYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0KIyBPcmdhbml6ZSBieSBzdGF0ZXMKCnN0YXRlXzIwMDggPC0gc2FoaWVfMjAwOCAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnN0YXRlXzIwMDkgPC0gc2FoaWVfMjAwOSAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnN0YXRlXzIwMTAgPC0gc2FoaWVfMjAxMCAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnN0YXRlXzIwMTEgPC0gc2FoaWVfMjAxMSAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnN0YXRlXzIwMTIgPC0gc2FoaWVfMjAxMiAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnN0YXRlXzIwMTMgPC0gc2FoaWVfMjAxMyAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnN0YXRlXzIwMTQgPC0gc2FoaWVfMjAxNCAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnN0YXRlXzIwMTUgPC0gc2FoaWVfMjAxNSAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnN0YXRlXzIwMTYgPC0gc2FoaWVfMjAxNiAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnN0YXRlXzIwMTcgPC0gc2FoaWVfMjAxNyAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnN0YXRlXzIwMTggPC0gc2FoaWVfMjAxOCAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDAgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnN0YXRlXzA4MTggPC0gcmJpbmQoc3RhdGVfMjAwOCwgc3RhdGVfMjAwOSwgc3RhdGVfMjAxMCwgc3RhdGVfMjAxMSwgc3RhdGVfMjAxMiwgCiAgICAgICAgICAgICAgICAgICAgc3RhdGVfMjAxMywgc3RhdGVfMjAxNCwgc3RhdGVfMjAxNSwgc3RhdGVfMjAxNiwgc3RhdGVfMjAxNywgc3RhdGVfMjAxOCkKYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0KcDEzOF9zdGF0ZV8yMDA4IDwtIHNhaGllXzIwMDggJT4lIAogIGZpbHRlcihhZ2VjYXQ9PTAgJiBzZXhjYXQgPT0gMCAmIHJhY2VjYXQgPT0gMCAmIGlwcmNhdCA9PSAzICYgY291bnR5X25hbWUgPT0gIiIpICU+JSBzZWxlY3QoLWNvdW50eV9uYW1lKQpwMTM4X3N0YXRlXzIwMDkgPC0gc2FoaWVfMjAwOSAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDMgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnAxMzhfc3RhdGVfMjAxMCA8LSBzYWhpZV8yMDEwICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMyAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKcDEzOF9zdGF0ZV8yMDExIDwtIHNhaGllXzIwMTEgJT4lIAogIGZpbHRlcihhZ2VjYXQ9PTAgJiBzZXhjYXQgPT0gMCAmIHJhY2VjYXQgPT0gMCAmIGlwcmNhdCA9PSAzICYgY291bnR5X25hbWUgPT0gIiIpICU+JSBzZWxlY3QoLWNvdW50eV9uYW1lKQpwMTM4X3N0YXRlXzIwMTIgPC0gc2FoaWVfMjAxMiAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDMgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnAxMzhfc3RhdGVfMjAxMyA8LSBzYWhpZV8yMDEzICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMyAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKcDEzOF9zdGF0ZV8yMDE0IDwtIHNhaGllXzIwMTQgJT4lIAogIGZpbHRlcihhZ2VjYXQ9PTAgJiBzZXhjYXQgPT0gMCAmIHJhY2VjYXQgPT0gMCAmIGlwcmNhdCA9PSAzICYgY291bnR5X25hbWUgPT0gIiIpICU+JSBzZWxlY3QoLWNvdW50eV9uYW1lKQpwMTM4X3N0YXRlXzIwMTUgPC0gc2FoaWVfMjAxNSAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDMgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnAxMzhfc3RhdGVfMjAxNiA8LSBzYWhpZV8yMDE2ICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMyAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKcDEzOF9zdGF0ZV8yMDE3IDwtIHNhaGllXzIwMTcgJT4lIAogIGZpbHRlcihhZ2VjYXQ9PTAgJiBzZXhjYXQgPT0gMCAmIHJhY2VjYXQgPT0gMCAmIGlwcmNhdCA9PSAzICYgY291bnR5X25hbWUgPT0gIiIpICU+JSBzZWxlY3QoLWNvdW50eV9uYW1lKQpwMTM4X3N0YXRlXzIwMTggPC0gc2FoaWVfMjAxOCAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDMgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCgpwMjUwX3N0YXRlXzIwMDggPC0gc2FoaWVfMjAwOCAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDIgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnAyNTBfc3RhdGVfMjAwOSA8LSBzYWhpZV8yMDA5ICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMiAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKcDI1MF9zdGF0ZV8yMDEwIDwtIHNhaGllXzIwMTAgJT4lIAogIGZpbHRlcihhZ2VjYXQ9PTAgJiBzZXhjYXQgPT0gMCAmIHJhY2VjYXQgPT0gMCAmIGlwcmNhdCA9PSAyICYgY291bnR5X25hbWUgPT0gIiIpICU+JSBzZWxlY3QoLWNvdW50eV9uYW1lKQpwMjUwX3N0YXRlXzIwMTEgPC0gc2FoaWVfMjAxMSAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDIgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnAyNTBfc3RhdGVfMjAxMiA8LSBzYWhpZV8yMDEyICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMiAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKcDI1MF9zdGF0ZV8yMDEzIDwtIHNhaGllXzIwMTMgJT4lCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDIgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnAyNTBfc3RhdGVfMjAxNCA8LSBzYWhpZV8yMDE0ICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMiAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKcDI1MF9zdGF0ZV8yMDE1IDwtIHNhaGllXzIwMTUgJT4lIAogIGZpbHRlcihhZ2VjYXQ9PTAgJiBzZXhjYXQgPT0gMCAmIHJhY2VjYXQgPT0gMCAmIGlwcmNhdCA9PSAyICYgY291bnR5X25hbWUgPT0gIiIpICU+JSBzZWxlY3QoLWNvdW50eV9uYW1lKQpwMjUwX3N0YXRlXzIwMTYgPC0gc2FoaWVfMjAxNiAlPiUgCiAgZmlsdGVyKGFnZWNhdD09MCAmIHNleGNhdCA9PSAwICYgcmFjZWNhdCA9PSAwICYgaXByY2F0ID09IDIgJiBjb3VudHlfbmFtZSA9PSAiIikgJT4lIHNlbGVjdCgtY291bnR5X25hbWUpCnAyNTBfc3RhdGVfMjAxNyA8LSBzYWhpZV8yMDE3ICU+JSAKICBmaWx0ZXIoYWdlY2F0PT0wICYgc2V4Y2F0ID09IDAgJiByYWNlY2F0ID09IDAgJiBpcHJjYXQgPT0gMiAmIGNvdW50eV9uYW1lID09ICIiKSAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkKcDI1MF9zdGF0ZV8yMDE4IDwtIHNhaGllXzIwMTggJT4lIAogIGZpbHRlcihhZ2VjYXQ9PTAgJiBzZXhjYXQgPT0gMCAmIHJhY2VjYXQgPT0gMCAmIGlwcmNhdCA9PSAyICYgY291bnR5X25hbWUgPT0gIiIpICU+JSBzZWxlY3QoLWNvdW50eV9uYW1lKQoKcDEzOF9zdGF0ZV8wODE4IDwtIHJiaW5kKHAxMzhfc3RhdGVfMjAwOCwgcDEzOF9zdGF0ZV8yMDA5LCBwMTM4X3N0YXRlXzIwMTAsIHAxMzhfc3RhdGVfMjAxMSwgcDEzOF9zdGF0ZV8yMDEyLCAKICAgICAgICAgICAgICAgICAgICBwMTM4X3N0YXRlXzIwMTMsIHAxMzhfc3RhdGVfMjAxNCwgcDEzOF9zdGF0ZV8yMDE1LCBwMTM4X3N0YXRlXzIwMTYsIHAxMzhfc3RhdGVfMjAxNywKICAgICAgICAgICAgICAgICAgICBwMTM4X3N0YXRlXzIwMTgpCnAyNTBfc3RhdGVfMDgxOCA8LSByYmluZChwMjUwX3N0YXRlXzIwMDgsIHAyNTBfc3RhdGVfMjAwOSwgcDI1MF9zdGF0ZV8yMDEwLCBwMjUwX3N0YXRlXzIwMTEsIHAyNTBfc3RhdGVfMjAxMiwgCiAgICAgICAgICAgICAgICAgICAgcDI1MF9zdGF0ZV8yMDEzLCBwMjUwX3N0YXRlXzIwMTQsIHAyNTBfc3RhdGVfMjAxNSwgcDI1MF9zdGF0ZV8yMDE2LCBwMjUwX3N0YXRlXzIwMTcsCiAgICAgICAgICAgICAgICAgICAgcDI1MF9zdGF0ZV8yMDE4KQpwX3N0YXRlXzA4MTggPC0gcmJpbmQocDEzOF9zdGF0ZV8wODE4LCBwMjUwX3N0YXRlXzA4MTgpCmBgYAoKYGBge3IsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCBmaWcuYXNwID0gMSwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTh9CnAxIDwtIHBfc3RhdGVfMDgxOCAlPiUgbXV0YXRlKHllYXI9YXMuZmFjdG9yKHllYXIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXByY2F0PWlmZWxzZShpcHJjYXQ9PTIsICJBdCBvciBiZWxvdyAyNTAlIEZQTCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBdCBvciBiZWxvdyAxMzglIEZQTCIpKSAlPiUKICBncm91cF9ieSh5ZWFyLCBpcHJjYXQpICU+JSBzdW1tYXJpc2UoYXZnLlVJID0gbWVhbihOVUkvTklQUikpICU+JQogIGdncGxvdChhZXMoeD15ZWFyLCB5PWF2Zy5VSSwgZ3JvdXA9aXByY2F0LCBjb2xvcj1pcHJjYXQsCiAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUoJzwvYnI+IFllYXI6ICcsIHllYXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICc8L2JyPiBVbmluc3VyZWQgcGVyY2VudGFnZTogJywgcm91bmQoYXZnLlVJLDIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9icj4gSW5jb21lIGxldmVsOiAnLCBpcHJjYXQpKSkgKwogIGdlb21fbGluZSgpICsKICBnZW9tX3BvaW50KCkgKwogIHRoZW1lX2Vjb25vbWlzdCgpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpICsKICBsYWJzKHRpdGxlPSJOYXRpb25hbCB1bmluc3VyYW5jZSByYXRlIGJ5IGluY29tZSBsZXZlbFxuIikgKwogIHlsYWIoIiIpICsKICB4bGFiKCIiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsKICB0aGVtZShheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQuaXRhbGljIiwgaGp1c3QgPSAwLjUpLAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkKCmdncGxvdGx5KHAxLCB0b29sdGlwID0gInRleHQiLCBoZWlnaHQgPSA0MDAsIHdpZHRoPTcwMCkgJT4lIAogIGNvbmZpZyhkaXNwbGF5TW9kZUJhciA9IEZBTFNFKSAlPiUKICBsYXlvdXQoaG92ZXJsYWJlbCA9IGxpc3QoYmdjb2xvciA9ICJ3aGl0ZSIsIGZvbnQgPSBsaXN0KGZhbWlseSA9ICJHZW9yZ2lhIikpLCAKICAgICAgICAgbGVnZW5kID0gbGlzdChvcmllbnRhdGlvbiA9ICJoIiwgeT0xLjA4KSkKYGBgCgoKCkhvdyBhcmUgaW5jb21lIGxldmVscyByZWxhdGVkIHRvIHRoZSB1bmluc3VyYW5jZSByYXRlPyBXZSBjaG9zZSB0byBmb2N1cyBvbiB0aGUgMTM4JSBvZiB0aGUgRmVkZXJhbCBQb3ZlcnR5IExldmVsIChGUEwpIGFuZCB0aGUgMjUwJSBvZiBGUEwuIFRoZSByZWFzb25pbmcgaXMgdGhhdCBmb3IgdGhlIHBvcHVsYXRpb24gd2l0aCBpbmNvbWUgbGV2ZWwgYmVsb3cgdGhlIDEzOCUgRlBMLCBpZiB0aGVpciBzdGF0ZXMgZXhwYW5kZWQgTWVkaWNhaWQgdW5kZXIgdGhlIEFmZm9yZGFibGUgQ2FyZSBBY3QgKEFDQSwgc2lnbmVkIGludG8gbGF3IGJ5IFByZXNpZGVudCBPYmFtYSBpbiAyMDEwIGFuZCB3ZW50IGludG8gZWZmZWN0IHN0YXJ0aW5nIDIwMTQpLCB0aGV5IG1heSBxdWFsaWZ5IGZvciBNZWRpY2FpZCBvciBDSElQLiBQb3B1bGF0aW9uIHRoYXQgZWFybnMgYW4gaW5jb21lIGJlbG93IHRoZSAyNTAlIEZQTCBtYXkgcXVhbGlmeSBmb3Igb3V0LW9mLXBvY2tldCBjb3N0IGFzc2lzdGFuY2Ugb24gU2lsdmVyIHBsYW5zIHNvbGQgdGhyb3VnaCB0aGUgTWFya2V0cGxhY2UuIAoKRnJvbSB0aGUgYWJvdmUgZ3JhcGhpYywgd2UgY2FuIHNlZSB0aGF0IHRoZSBsb3dlciB0aGUgaW5jb21lLCBhbHRob3VnaCB3aXRoIHNvbWUgbGV2ZWwgb2YgYXNzaXN0YW5jZSwgdGhlIGhpZ2hlciB1bmluc3VyYW5jZSByYXRlIGFjcm9zcyB0aGUgMTAgeWVhciBwZXJpb2QuIFdlIGNhbiBhbHNvIG9ic2VydmUgY2xlYXJseSB0aGF0IHRoZSB1bmluc3VyYW5jZSByYXRlIGRyb3BwZWQgc2lnbmlmaWNhbnRseSBiZXR3ZWVuIDIwMTMgYW5kIDIwMTQsIGJlY2F1c2Ugb2YgdGhlIEFDQS4KCioqSG92ZXIgb3ZlciBkYXRhIHBvaW50cyBvZiBpbnRlcmVzdCoqCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFzcCA9IDEsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD04fQppbmNvbWUgPC0gcmVhZC5jc3YoIkRhdGEvSG9uZ2p1ZV9CRUFfSW5jb21lX1Blcl9DYXBpdGFfYnlfU3RhdGVfMTk5MC0yMDE5LmNzdiIpCgppbmNvbWUgPC0gaW5jb21lICU+JSBtdXRhdGUoZmlwcyA9IGlmZWxzZShzdHJfbGVuZ3RoKEdlb0ZpcHMpIDwgNSwgcGFzdGUwKDAsIEdlb0ZpcHMpLCBHZW9GaXBzKSkgJT4lCiAgc2VsZWN0KC1HZW9GaXBzKSAlPiUKICBmaWx0ZXIoeWVhciAlaW4lIDIwMDg6MjAxOCkKCnN0YXRlX3NpbXBsZSA8LSBzdGF0ZV8wODE4ICU+JSBzZWxlY3QoeWVhciwgTlVJLCBOSVBSLCBmaXBzKQoKaW5jX2luc3VyIDwtIGxlZnRfam9pbihpbmNvbWUsIHN0YXRlX3NpbXBsZSkKCnAyIDwtIGdncGxvdChpbmNfaW5zdXIsIGFlcyh4PU5VSS9OSVBSLCB5PWluY29tZV9wZXJfY2FwaXRhLCBjb2xvcj1HZW9OYW1lLCBhbHBoYT0wLjcsIHNoYXBlPWFzLmZhY3Rvcih5ZWFyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZSgnPC9icj4gWWVhcjogJywgeWVhciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9icj4gU3RhdGU6ICcsIEdlb05hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzwvYnI+IFVuaW5zdXJlZCBwZXJjZW50YWdlOiAnLCByb3VuZChOVUkvTklQUiwyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9icj4gSW5jb21lIGxldmVsOiAnLCBpbmNvbWVfcGVyX2NhcGl0YSkpKSArCiAgZ2VvbV9wb2ludCgpICsKICB0aGVtZV9lY29ub21pc3QoKSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKCkgKwogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IGRvbGxhcikgKwogIHRoZW1lKGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZC5pdGFsaWMiLCBoanVzdCA9IDAuNSksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgbGFicyh0aXRsZSA9ICJIb3cgZG9lcyBpbmNvbWUgYWZmZWN0IHRoZSB1bmluc3VyYW5jZSByYXRlPyIsIHN1YnRpdGxlID0gIlN0YXRlcyBieSBjb2xvciwgeWVhcnMgYnkgc2hhcGUiKSArCiAgeGxhYigiUmF0ZSBvZiB1bmluc3VyYW5jZSIpICsgCiAgeWxhYigiSW5jb21lIHBlciBjYXBpdGFcbiIpCgpnZ3Bsb3RseShwMiwgdG9vbHRpcCA9ICJ0ZXh0IiwgaGVpZ2h0ID0gNDAwLCB3aWR0aD03ODApICU+JSAKICBjb25maWcoZGlzcGxheU1vZGVCYXIgPSBGQUxTRSkgJT4lCiAgbGF5b3V0KGhvdmVybGFiZWwgPSBsaXN0KGJnY29sb3IgPSAid2hpdGUiLCBmb250ID0gbGlzdChmYW1pbHkgPSAiR2VvcmdpYSIpKSkKYGBgCgoKSGVyZSBpcyBhIG1vcmUgZGV0YWlsZWQgbG9vayBpbnRvIHRoaXMgaW5jb21lLXVuaW5zdXJhbmNlIHJlbGF0aW9uc2hpcC4gV2UgY2FuIHNlZSB0aGF0LCBpbiBnZW5lcmFsLCB0aGUgbG93ZXIgdGhlIGluY29tZSBwZXIgY2FwaXRhIChvZiBhIGNlcnRhaW4gc3RhdGUgaW4gYSBnaXZlbiB5ZWFyKSwgdGhlIGhpZ2hlciB0aGUgc3RhdGUtbGV2ZWwgdW5pbnN1cmVkIHJhdGUuIChOb3RlOiBTdGF0ZXMgYXJlIGRpZmZlcmVudGlhdGVkIHVzaW5nIGNvbG9yIGFuZCB5ZWFycyBhcmUgZGlmZmVyZW50aWF0ZWQgdXNpbmcgc2hhcGUuKQogIApgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0Kc3RhdGVzIDwtIHJlYWRPR1IoZHNuID0gIkRhdGEvZ3pfMjAxMF91c18wNDBfMDBfNTAway5qc29uIikKCmR0IDwtIGluY19pbnN1ciAlPiUKICBtdXRhdGUoeWVhcj1hcy5mYWN0b3IoeWVhciksIHVuaW5zdXJlZCA9IHJvdW5kKE5VSS9OSVBSLDIpLCBzdGF0ZSA9IGFzLmNoYXJhY3RlcihHZW9OYW1lKSkgJT4lIAogIHNlbGVjdCh5ZWFyLCBzdGF0ZSwgdW5pbnN1cmVkLCBpbmNvbWVfcGVyX2NhcGl0YSkgJT4lIGZpbHRlcih5ZWFyPT0yMDA4KQoKZHQuZ2VvIDwtIGR0ICU+JSBtdXRhdGVfZ2VvY29kZShzdGF0ZSkKYGBgCgpUbyB2aXN1YWxpemUgdGhpcyBpbiBhIG1hcCwgd2UgY3JlYXRlZCBhIExlYWZsZXQgbWFwIHdpdGggc2VwYXJhdGUgbGF5ZXJzIGZvciB0aGUgdW5pbnN1cmFuY2UgcmF0ZSBhbmQgaW5jb21lIGxldmVsLCBzaG93biBiZWxvdyBmb3IgdGhlIHllYXJzIDIwMDgtMjAxOCAoYXZlcmFnZWQpLiBUaGUgY29sb3IgZGVuc2l0eSBjb3JyZXNwb25kcyB0byB0aGUgdW5pbnN1cmFuY2UgcmF0ZSBhbmQgdGhlIGF2ZXJhZ2UgaW5jb21lIHBlciBjYXBpdGEsIHJlc3BlY3RpdmVseS4gVXNpbmcgdGhpcyB2aXN1YWxpemF0aW9uIHdlIGNhbiBvYnNlcnZlIHRoYXQgaW4gZ2VuZXJhbCwgdGhlIG5vcnRoZWFzdCBhbmQgd2VzdCBjb2FzdCByZWdpb25zIGhhZCBoaWdoZXIgaW5jb21lcyBwZXIgY2FwaXRhLCB3aGlsZSB0aGUgc291dGhzLCBtaWR3ZXN0LCBhbmQgQWxhc2thIHdlcmUgc3RydWdnbGluZyB3aXRoIHRoZSBoaWdoZXN0IHVuaW5zdXJhbmNlIHJhdGUuIAoKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpkdCA8LSBpbmNfaW5zdXIgJT4lCiAgbXV0YXRlKHVuaW5zdXJlZCA9IHJvdW5kKE5VSS9OSVBSLDIpLCBzdGF0ZSA9IGFzLmNoYXJhY3RlcihHZW9OYW1lKSkgJT4lIAogIHNlbGVjdCh5ZWFyLCBzdGF0ZSwgdW5pbnN1cmVkLCBpbmNvbWVfcGVyX2NhcGl0YSkgJT4lCiAgbXV0YXRlX2dlb2NvZGUoc3RhdGUpCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD02fQojIGR0X3llYXIgPC0gZHQgJT4lIGZpbHRlcih5ZWFyPT0yMDA4KQpkdF95ZWFyIDwtIGR0ICU+JSBncm91cF9ieShzdGF0ZSkgJT4lIAogIHN1bW1hcmlzZShpbmNvbWVfcGVyX2NhcGl0YT1tZWFuKGluY29tZV9wZXJfY2FwaXRhKSwgdW5pbnN1cmVkPW1lYW4odW5pbnN1cmVkKSwgCiAgICAgICAgICAgIGxvbj1tZWFuKGxvbiksIGxhdD1tZWFuKGxhdCkpICU+JQogIG11dGF0ZShzdGF0ZT1hcy5mYWN0b3Ioc3RhdGUpKQoKc3RhdGVzLm1lcmdlZCA8LSBtZXJnZSh4PXN0YXRlcywgeT1kdF95ZWFyLCBieS54PSJOQU1FIiwgYnkueT0ic3RhdGUiKQoKcGFsMSA8LSBjb2xvckJpbigiWWxPclJkIiwgZG9tYWluID0gc3RhdGVzLm1lcmdlZCR1bmluc3VyZWQsIGJpbnMgPSBjKDAsIDAuMDUsIDAuMSwgMC4xNSwgMC4yLCAwLjI1LCAwLjMpKQpwYWwyIDwtIGNvbG9yQmluKCJCdUduIiwgZG9tYWluID0gc3RhdGVzLm1lcmdlZCRpbmNvbWVfcGVyX2NhcGl0YSwgYmlucyA9IGMoMjAwMDA6ODUwMDApKQoKcG9wdXAgPSBwYXN0ZSgiU3RhdGU6ICIsIHN0YXRlcy5tZXJnZWRAZGF0YSROQU1FLAogICAgICAgICAgICAgICI8YnI+SW5jb21lIHBlciBjYXBpdGE6ICIsIHJvdW5kKHN0YXRlcy5tZXJnZWRAZGF0YSRpbmNvbWVfcGVyX2NhcGl0YSwyKSwKICAgICAgICAgICAgICAiPGJyPlVuaW5zdXJlZCByYXRlOiAiLCByb3VuZChzdGF0ZXMubWVyZ2VkQGRhdGEkdW5pbnN1cmVkLDIpKQoKbGVhZmxldChzdGF0ZXMubWVyZ2VkKSAlPiUgYWRkVGlsZXMoKSAlPiUKICBzZXRWaWV3KC05NiwgMzcuOCwgNCkgJT4lCiAgYWRkUG9seWdvbnMoZmlsbENvbG9yID0gfnBhbDEodW5pbnN1cmVkKSwKICAgICAgICAgICAgZmlsbE9wYWNpdHkgPSAwLjYsIGNvbG9yID0gImRhcmtncmV5Iiwgd2VpZ2h0ID0gMS41LAogICAgICAgICAgICBwb3B1cCA9IHBvcHVwLCBncm91cD0iVW5pbnN1cmVkIHJhdGUiKSU+JQogIGFkZFBvbHlnb25zKGZpbGxDb2xvciA9IH5wYWwyKGluY29tZV9wZXJfY2FwaXRhKSwgCiAgICAgICAgICAgIGZpbGxPcGFjaXR5ID0gMSwgY29sb3IgPSAid2hpdGUiLCB3ZWlnaHQgPSAyLjAsIAogICAgICAgICAgICBwb3B1cCA9IHBvcHVwLCBncm91cD0iSW5jb21lIGxldmVsIikgJT4lCiAgYWRkTGF5ZXJzQ29udHJvbCgKICAgIGJhc2VHcm91cHMgPSBjKCJVbmluc3VyYW5jZSByYXRlIiwgIkluY29tZSBsZXZlbCIpLAogICAgb3B0aW9ucyA9IGxheWVyc0NvbnRyb2xPcHRpb25zKGNvbGxhcHNlZCA9IEZBTFNFKSkKYGBgCgpUbyBtYWtlIGl0IGNsZWFyZXIgYW5kIGVhc2llciB0byB1bmRlcnN0YW5kLCB3ZSBjcmVhdGVkIGEgZGF0YSB0YWJsZSBmb3Igb3VyIHVzZXJzIHRvIGV4cGxvcmUgdGhlIHN0YXRpc3RpY3Mgb2YgdGhlaXIgaW50ZXJlc3Q6CgpgYGB7ciwgZXZhbD1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpkdCA8LSBpbmNfaW5zdXIgJT4lCiAgbXV0YXRlKHllYXI9YXMuZmFjdG9yKHllYXIpLCB1bmluc3VyZWQgPSByb3VuZChOVUkvTklQUiwyKSkgJT4lIAogIHNlbGVjdCh5ZWFyLCBHZW9OYW1lLCB1bmluc3VyZWQsIGluY29tZV9wZXJfY2FwaXRhKSAKCmNvbG5hbWVzKGR0KSA8LSBjKCJZZWFyIiwgIlN0YXRlIE5hbWUiLCAiVW5pbnN1cmFuY2UgUmF0ZSIsICJJbmNvbWUgcGVyIENhcGl0YSIpCgpkdCAlPiUKICBkYXRhdGFibGUoCiAgICBmaWx0ZXIgPSBsaXN0KHBvc2l0aW9uID0gInRvcCIpLAogICAgb3B0aW9ucyA9IGxpc3QobGFuZ3VhZ2UgPSBsaXN0KHNTZWFyY2ggPSAiRmlsdGVyOiIpKSkKYGBgCg==